angularjestjsngrxangular-testngrx-test

Use SpyOn on provider that has string value


I have a class that I am trying to test. The class has a service Injected in as such:

 constructor(private actions$: Actions, @Inject('NotificationHandlerService') private notificationService: INotificationHandlerService) {}

In the spec.ts I just provided it using a value as I just want to test that the display function gets called:

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        provideMockActions(() => actions$),
        RequirementNotificationsEffects,
        {
          provide: 'NotificationHandlerService',
          useValue: {
            display: () => {}
          }
        },
        provideMockStore({ initialState: requirementInitialState})
      ],
    });

    reqNotificationEffects = TestBed.inject(RequirementNotificationsEffects);
  });

I am then testing to see if the display function gets called however I receive an error on running the test stating Cannot spyOn on a primitive value; string given Test:

    it('Call notification service to display message to user.', () => {
      const testOwner = new OwnerGroupReference({name: 'Test Owner'}) ;
      const action = reqActions.removeOwnersWithSubmission({ owners: [{testOwner}]});
      const notificationDisplaySpy = jest.spyOn('NotificationHandlerService', 'display');

      actions$ = hot("-a", { a: action });

      expect(reqNotificationEffects.removeOwners$).toSatisfyOnFlush(() => {
        expect(notificationDisplaySpy).toHaveBeenCalled();
      });
    });

anyone know what I should be doing?


Solution

  • Extract useValue in a const variable

    const mockService = {
      display: jest.fn();
    }
    beforeEach(() => {
      TestBed.configureTestingModule({
        providers: [
          provideMockActions(() => actions$),
          RequirementNotificationsEffects,
          {
            provide: 'NotificationHandlerService',
            useValue: mockService
          },
          provideMockStore({ initialState: requirementInitialState})
        ],
      });
    
      reqNotificationEffects = TestBed.inject(RequirementNotificationsEffects);
    });
    
    it('Call notification service to display message to user.', () => {
      const testOwner = new OwnerGroupReference({name: 'Test Owner'}) ;
      const action = reqActions.removeOwnersWithSubmission({ owners: [{testOwner}]});
    
      actions$ = hot("-a", { a: action });
    
      expect(reqNotificationEffects.removeOwners$).toSatisfyOnFlush(() => {
        expect(mockService.display).toHaveBeenCalled();
      });
    });
    

    You can implement this with spyOn also