angular-redux / store

Angular 2+ bindings for Redux
MIT License
1.34k stars 205 forks source link

Tests with MockNgRedux : Observable provided does not seems to update template #523

Open Vespira opened 6 years ago

Vespira commented 6 years ago

This is a...

What toolchain are you using for transpilation/bundling?

Environment

NodeJS Version: 8.10.0 Typescript Version: 2.6.0 Angular Version: 5.2.9 @angular-redux/store version: 7.0.0 @angular/cli version: (if applicable) 1.7.4 OS: Windows 10

Link to repo showing the issues

I haven't set up all the soup on a plunker or stackblitz, but I have posted a post here : https://stackoverflow.com/questions/50137185/testing-component-template-with-angular-and-redux

Expected Behaviour:

I try to unit test a component. I expect a template to display something when I have an Observable which returns me a state change. I use MockNgRedux to stub the value, I subscribe to the Observable, subscribe callback is called, and I should be able to query by CSS a DOM element because I have now provided a value into the mocked state.

product-list.component.html :

<div class="product-list"
  *ngIf="(basket$ | async).length > 0">
...
</div>

product-list.component.ts :

 @select(['saleState', 'basket'])
 readonly basket$: Observable<Product[]>;

product-list.component.spec.ts :

it('should show the product list when a product is added to basket', done => {
   const basket$ = MockNgRedux.getSelectorStub<RootStateInterface, Product[]>(['saleState', 'basket']);

   basket$.next([
     new Product('name', 12.0) // simplified for example purpose
   ]);
   basket$.complete();

   fixture.componentInstance.basket$
      .filter(val => val && val.length > 0)
      .subscribe(val => {
        console.log(val); // it works I see my inserted product
        fixture.detectChanges();
        const container = fixture.debugElement.query(By.css('div.product-list')); // <- container is null
        expect(container).toBeDefined();
        done();
   });
});

Actual Behaviour:

I try to unit test a component. I expect a template to display something when I have an Observable which returns me a state change. I use MockNgRedux to stub the value, I subscribe to the Observable, subscribe callback is called, but my query selector does not works : because nothing is displayed in the DOM.

Stack Trace/Error Message:

Additional Notes:

I tried to use the done Jasmine callback, or the Angular async test to achieve this; but it does not change the behavior. If I replace in the *ngIf of my component, the variable provided by redux and I put a ReplaySubject created into the component, and then do a next() on it, it will correctly display the DOM element.

Thank you :)

yduartep commented 5 years ago

I have the same problem. Any updates?

gregkopp commented 5 years ago

Have you tried using fakeasync and tick?