I'm trying to test a component which edits shopping list items.
When first loaded, the pertinent state values it receives via subscribing to store.select are:
editedIngredient: null,
editedIngredientIndex: -1
With these values, it'll ensure that the class' editMode property is set to false.
During testing, I am trying to update the state once the component has loaded.
What i'm trying to achieve is updating the editedIngredient and editedIngredientIndex properties to a truthy value in my component, hence allowing the editMode prop to be set to true.
When trying the below code, I am able to get the component to render and editMode is initally set to false.
Once the state is updated inside my test however, the store.select subscriber does not update, meaning the test just finishes without editMode ever being set to true.
Component code (ShoppingEditComponent)
ngOnInit() {
this._subscription = this.store.select('shoppingList').subscribe(stateData => {
if (stateData.editedIngredientIndex > -1) {
this.editMode = true; // I want to update my state later so that I set this value
return;
}
this.editMode = false; // I start with this value
});
}
Test code
let store: MockStore<State>;
const initialState: State = {
editedIngredient: null,
editedIngredientIndex: -1
};
const updatedShoppingListState: State = {
editedIngredient: seedData[0],
editedIngredientIndex: 0
};
let storeMock;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [
ShoppingEditComponent
],
providers: [
provideMockStore({ initialState }),
]
});
});
Test Attempt 1
it('should have \'editMode = true\' when it receives a selected ingredient in updated state',
fakeAsync(() => {
const fixture = TestBed.createComponent(ShoppingEditComponent);
const componentInstance = fixture.componentInstance;
// no change detection occurs, hence the subscribe callback does not get called with state update
store.setState(updatedShoppingListState);
expect(componentInstance['editMode']).toEqual(true);
})
);
Test Attempt 2
it('should have \'editMode = true\' when it receives a selected ingredient in updated state',
fakeAsync((done) => {
const fixture = TestBed.createComponent(ShoppingEditComponent);
const componentInstance = fixture.componentInstance;
fixture.whenStable().then(() => {
store.setState(updatedShoppingListState);
expect(componentInstance['editMode']).toEqual(true);
done();
});
})
);
- The problem I am having with attempt 1 is that the change detection doesn't occur.
- The problem I am having with attempt 2 is that the change detection doesn't occur if I omit the
done()callback.
However, if I include thedone()callback, I get an error stating thatdone() is not a function
For reference: I found the example for mocking the store from the NgRx docs (i'm on Angular 8, so this example is most relevant for me)
I am using Karma/Jasmine for my tests.
Any guidance would be really helpful.