Search code examples
testingmockingjasminesubject

Mocking a return value for a Subject - Unit Testing with Jasmine


I'm unit testing and part of the testing has a Subject. I'm new to Subjects and get the general gist of how they work but am struggling to mock a return value on one. I've tried various ways in the hopes of stumbling on the correct way like using a spy and returnvalue to return the number 3.

In the component:

.... 
private searchEvent: Subject<string> = new Subject<string>();

....
      this.searchEvent.pipe(debounceTime(500)).subscribe(value => {
        if (value.length >= 3) {
          this.retrieveAssets(value);
        }
      })
....

In my spec file I basically have:

        component['searchStockEvent'].subscribe(x=> of(3));

        fixture.whenStable().then(() => {
          expect(component['retrieveAssets']).toHaveBeenCalled();
        });

Solution

  • searchEvent being private will make it difficult to call next directly on the subject so you have to find a way of what makes searchEvent emit a value of greater than 3 and go that route.

    For this demo, we will make it public:

    .... 
    public searchEvent: Subject<string> = new Subject<string>();
    
    ....
          this.searchEvent.pipe(debounceTime(500)).subscribe(value => {
            if (value.length >= 3) {
              this.retrieveAssets(value);
            }
          })
    ....
    
    import { fakeAsync, tick } from '@angular/core/testing';
    it('should call retrieve assets', fakeAsync(() => {
      component.searchEvent.next(3);
      // we need to pass 501ms in a fake way
      tick(501);
      expect(component.retreiveAssets).toHaveBeenCalled();
    }));