2

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!

ChristyPiffat
  • 359
  • 1
  • 6
  • 26

0 Answers0