简体   繁体   中英

mocking a promise in jest mock module factory

I'm writing some units tests and need to mock a named export from a file, but it doesn't seem to work when the export is a function that returns a promise.

For example, I have a module located at lib/api.js that exports a single function called getFoo , which itself returns axios.get('/foo').

In my tests, I want to mock the return value of getFoo to be a resolved promise with the foo payload, so I mock using a module factory:

import * as api from 'lib/api';
jest.mock('lib/api', () => ({
  getFoo: jest.fn(() => Promise.resolve('foo')),
});

and then in my test I want to assert that getFoo was called as part of larger process of chained promises.

it('getBar should call getFoo', () => {
  return getBar().then(() => {
    expect(api.getFoo).toHaveBeenCalled();
  });
})

The error I get here is cannot read property 'then' of undefined , as though the jest function used in the mocked module factory is not returning the promise.

If the return value for getFoo is not a promise, it works as expected. If I use jest.fn() as the value for getFoo, and then in the test itself mock the implementation...

it('getBar should call getFoo', () => {
  api.getFoo.mockImplementation(() => Promise.resolve("foo"));
  return getBar().then(() => {
    expect(api.getFoo).toHaveBeenCalled();
  });
})

...then it works. My understanding is that the jest.fn(() => {}) should just be a shorter way of defining the implementation, so I am not sure why I am getting the error. Any help appreciated.

Thanks.

More Info:

The lib/api looks like this...

import axios from 'axios';

export const getFoo = (host: string, accessToken: string): Promise<{}> =>
  axios.get(`${host}/foo`, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    }
  })
  // return foo
  .then((response) => response.data)
  .catch(() => {
    throw new Error('Failed to load foo');
  });

When I console log the mocked getFoo function while the test is running, it shows up as...

getFoo function mockConstructor() {
  return fn.apply(this, arguments);                                                                         }

First thing, you need to mock it before importing it:

jest.mock('lib/api');

import * as api from 'lib/api';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM