Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nest JS - Issue writing Jest Test Case for a function returning Observable Axios Response

I am fairly new to NestJS + Typescript + RxJs tech stack. I am trying to write a unit test case using Jest for one of my functions but not sure if doing it correctly.

component.service.ts

public fetchComponents(queryParams) {
  const url = this.prepareUrl(queryParams);

  const data$ = this.httpService.get(url);

  return data$
    .pipe(map(({ data }) => data));
}

component.sevice.spec.ts

Test case works and passes

describe('fetchComponents', () => {
  const query = {
    limit: 10,
    offset: 0
  };

  const result: AxiosResponse = {
    data: 'Components',
    status: 200,
    statusText: 'OK',
    headers: {},
    config: {}
  };
  it('should return Dummy Data when called successfully', () => {
    componentService.prepareUrl = jest.fn();

    jest.spyOn(httpService, 'get').mockImplementation(() => of(result));

   componentService.fetchComponents(market, query)
    .subscribe(
      (res) => {
        expect(res).toEqual('Components');
      }
    );
  });
});

Can you please provide suggestions and pointers on how exactly I should test this function. Also without using Library like marbel-rx I am not sure if I am testing it correctly. Is there something else also which I should test?

like image 474
Achyut Avatar asked Mar 16 '19 18:03

Achyut


1 Answers

Since Observables are asynchronous, you have to add the asynchronous done paramter and call done() after the expect that is executed last. Otherwise, jest will finish the test run after subscribe() is called without waiting for the execution of the asynchronous execution of subscribe's callback. Try to make your test fail by for example by expecting 'Komponents'. The test will not fail.

Also, I'd recommend to use mockImplementationOnce instead of mockImplementation when possible, to avoid implicitly reusing mock behaviors in later calls and therewith creating implicit dependencies.

it('should return Dummy Data when called successfully', done => {
// Add done parameter                                   ^^^^
  componentService.prepareUrl = jest.fn();

  jest.spyOn(httpService, 'get').mockImplementationOnce(() => of(result));
// Prefer mockImplementationOnce                   ^^^^

  componentService.fetchComponents(market, query)
    .subscribe(
      (res) => {
        expect(res).toEqual('Components');
        done();
//      ^^^^^^  Call done() when test is finished
      }
    );
});
like image 50
Kim Kern Avatar answered Oct 31 '22 15:10

Kim Kern