15

I'm using Jest and Typescript. I have a async function that returns nothing (void). How do I mock returning void? I tried the below

const myMockFn = jest.fn().mockImplementationOnce(() => Promise.resolve(void));
jest.mock('../config', () => ({
  setup: async () =>
  myMockFn(),
}));

but I get the compilation error

Expression expected.

related to "Promise.resolve(void)".

Dave
  • 15,639
  • 133
  • 442
  • 830

2 Answers2

29

void used here in value position is javascript operator. It is a unary operator i.e. it accepts a single argument. Thus the error.

void as a typescript type should be used in type position to express that function return value will not be observed.

const myMockFn = jest.fn().mockImplementationOnce(() => Promise.resolve());

That's enough to mock a function with Promise<void> return type.

aleksxor
  • 7,535
  • 1
  • 22
  • 27
8

You can mock a function that returns Promise<void> with:

jest.fn().mockResolvedValue(undefined)

If you try to capture the return value of a void function, you get undefined:

function foo(): void {
  console.log('foo called');
}

console.log(foo());

// foo called
// undefined

Additionally, Promise<void> appears to be the same as Promise<undefined>:

console.log(Promise.resolve());
// Promise { undefined }

console.log(Promise.resolve(undefined));
// Promise { undefined }

undefined is compatible with void and can be the resolved value:

interface Bar {
  foo(): Promise<void>;
}

describe('StackOverflow', () => {
  test('mock Promise<void>', async () => {
    const mockBar: Bar = {
      foo: jest.fn().mockResolvedValueOnce(undefined),
    };
    await mockBar.foo();
  });
});
Hand-E-Food
  • 12,368
  • 8
  • 45
  • 80