C0ZEN
C0ZEN

Reputation: 934

Testing the result of a promise with Jest inside a function

The jest documentation cover the case where a given function return a Promise and demonstrate how to test it.
But how do I test a void function calling the .then of a Promise inside the function?

Here is an example on how I was thinking about doing it nevertheless this is not working.

The function

function dummyFunction(): void {
   dummyService.getDummy$().then((dummy: Dummy): void => {
      console.log(`Dummy fetched`);
   });
}

The tests

describe(`dummyFunction()`, (): void => {
   let dummyServiceGetDummy$Spy: jest.SpyInstance;
   let consoleLogSpy: jest.SpyInstance;

   beforeEach((): void => {
      dummyServiceGetDummy$Spy = jest.spyOn(dummyService, `getDummy$`).mockImplementation();
      consoleLogSpy = jest.spyOn(console, `log`).mockImplementation();
   });

   it(`should fetch dummy`, (): void => {
      expect.assertions(2);

      dummyFunction();

      expect(dummyServiceGetDummy$Spy).toHaveBeenCalledTimes(1);
      expect(dummyServiceGetDummy$Spy).toHaveBeenCalledWith();
   });

   describe(`when dummy was successfully fetched`, (): void => {
      beforeEach((): void => {
         dummyServiceGetDummy$Spy.mockReturnValue((): Promise<void> => Promise.resolve());
      });

      it(`should log`, (): void => {
         expect.assertions(2);

         dummyFunction();

         expect(consoleLogSpy).toHaveBeenCalledTimes(1);
         expect(consoleLogSpy).toHaveBeenCalledWith(`Dummy fetched`);
      });
   });
});

Dependencies

"jest": "26.0.1"
"ts-jest": "26.0.0"

Upvotes: 1

Views: 2732

Answers (1)

Estus Flask
Estus Flask

Reputation: 222503

Promise encapsulation is an antipattern. dummyFunction should return a promise to chain in order to be properly reused and tested:

function dummyFunction(): void {
   return dummyService.getDummy$().then((dummy: Dummy): void => {
      console.log(`Dummy fetched`);
   });
}

Then it can be tested with built-in Jest promise support:

   it(`should fetch dummy`, async () => {
      await expect(dummyFunction()).resolves.toBe(undefined);

      expect(dummyServiceGetDummy$Spy).toHaveBeenCalledWith();
      expect(consoleLogSpy).toHaveBeenCalledWith(`Dummy fetched`);
   });

Upvotes: 2

Related Questions