I am writing an ngrx effect and trying to test it. However, the effect calls a service that calls an API that will require authentication. As a result, I am trying to create a spy in Jasmine to handle returning the data. This is my first time using ngrx effects, so I am really unsure where to put different parts of the code. Nothing I have done is allowing this test to run correctly.
The effect is a very simple one as follows:
@Effect() itemSelected: Observable<Action> = this.d.pessimisticUpdate('ITEM_SELECTED', {
run: (action: ItemSelected) => {
return this.myService.getItemById(action.payload).map((res) => ({
type: 'ITEM_INFO_RETURNED',
payload: res
}));
},
onError: (a: ItemSelected, error) => {
console.error('Error', error);
}
});
constructor(private d: DataPersistence<ItemState>, private myService: MyService) {
// add auth headers here
}
My test is currently written as follows:
describe('ItemEffects', () => {
let actions: Observable<any>;
let effects: ItemEffects;
let myService = jasmine.createSpyObj('MyService', ['getItemById']);
let item1: Item = {id: 1, name: 'Item 1'};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
StoreModule.forRoot({}),
],
providers: [
ItemEffects,
DataPersistence,
provideMockActions(() => actions),
{
provide: MyService,
useValue: myService
}
],
});
effects = TestBed.get(ItemEffects);
});
describe('someEffect', () => {
it('should work', async () => {
myService.getItemById.and.callFake(function (id) {
return items.find((r) => r.id === id);
});
actions = hot('-a-|', { a:{ type:'ITEM_INFO_RETURNED', payload:1}});
expect(effects.itemSelected).toEqual(
{ type: 'ITEM_INFO_RETURNED', payload: { item1 } }
);
});
});
});
This is still attempting to use the production MyService (requiring authentication). If I move the myService override out of the provider and into the actual test,
TestBed.overrideProvider(MyService, { useValue: myService });
I get an error that it cannot read the property "itemSelected" of undefined, which would be when I am calling the effects at the very end of the test.
I am really new to ngrx, as well as to TestBed. Is there somewhere else I should be defining this Jasmine spy? Should I be using something other than createSpyOn for this?
Thanks in advance!