1

I have a React component with the following dependency:

import { fetchUsers } from '../../api/';

This is utility function that returns a Promise.

When attempting to mock this using Jest, I've been unable to do this on a per test basis within a describe().

The only way I've been able to mock fetchUsers is to jest.mock() at the top of the file for the entire test suite.

import x from './x'

jest.mock('../../../../src/api/', () => ({
    fetchUsers: jest.fn(() => Promise.resolve({ users: [] })),
}));

This doesn't suit as I need to test the .then() (Promise.resolve) and the .catch (Promise.reject) in different tests. With the above, I can only test the .then()

Does anyone know how to use Jest to mock a React Component's dependency which returns a promise on a per test basis?

Thanks

Joshua
  • 3,055
  • 3
  • 22
  • 37
James Gallagher
  • 389
  • 2
  • 4
  • 12

1 Answers1

1

Jest mock functions can change implementation:

jest.mock('../../../../src/api/', () => ({
    fetchUsers: jest.fn()
}));

...
const { fetchUsers } = require('../../../../src/api/');
fetchUsers.mockImplementation(() => Promise.resolve({ users: [] }));
// do something that calls fetchUsers

As explained in this answer, it's also possible to mock a property on transpiled * import any time due to how ES modules work:

import * as api from '../../../../src/api/';

...
jest.spyOn(api, 'fetchUsers').mockImplementation(() => Promise.resolve({ users: [] }));
// do something that calls fetchUsers
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Hi @estus, I was able to get the jest.mock()/require() method working but was unable to get the import/spyOn() method working... getting the error... Cannot set property fetchUsers of # which has only a getter... do you know why this could be? – James Gallagher Sep 10 '18 at 20:27
  • @JamesGallagher This is a known issue, https://github.com/webpack/webpack/issues/4039 . This depends on how modules are configured. It looks like they aren't configured properly in create-react-app Jest setup, I would expect them to be CJS in Jest while they are not. I guess the second solution doesn't fit your setup. – Estus Flask Sep 11 '18 at 12:18