Search code examples
javascripttypescriptunit-testingjestjsts-jest

How to test an imported function returning a Promise in Jest?


I have this very simple function, and I must write a test. The goal is to fulfill the coverage threshold.

import { lambdaPromise } from '@helpers';

export const main = async event => lambdaPromise(event, findUsers);

The lambdaPromise() function returns a Promise. I am trying to mock it, then tell if it was called. Here's what I have:

import { main, findUsers } from '../src/lambdas/user/findUsers';
import { lambdaPromise } from '@helpers';

const mockEvent = {
  arguments: {
    userDataQuery: {
      email: '[email protected]'
    }
  }
};

const mockLambdaPromise = jest.fn();

jest.mock('@helpers', () => ({
  lambdaPromise: jest.fn().mockImplementation(() => mockLambdaPromise)
}));

describe('findUsers', () => {
  it('should have a main function', async () => {
    const mockPromise = main(mockEvent);
    expect(mockPromise).toBeInstanceOf(Promise);
    expect(mockLambdaPromise).toBeCalledWith(mockEvent, findUsers);
  });
});

Now mockLambdaPromise never gets called. How to fix that?


Solution

  • Your mock returns a function, but you didn't call that function. The following makes it pass.

    jest.mock("./helpers", () => ({
      lambdaPromise: jest
        .fn()
        .mockImplementation((a, b) => mockLambdaPromise(a, b)),
    }));
    

    The complexity of that mock can be reduced by just mocking the resolved value with a spy:

    import { main, findUsers } from "./findUsers";
    import * as helpers from "./helpers";
    
    describe("findUsers", () => {
      it("should have a main function", async () => {
        const spy = jest.spyOn(helpers, "lambdaPromise").mockResolvedValue();
        await main(mockEvent);
        expect(spy).toBeCalledWith(mockEvent, findUsers);
      });
    });