jest: jest.setMock does not work with jest.dontMock

Say I have a test, and in it, I have a module, ../myModuleToTest that requires someNodeLib. When I do the following, things get screwed up:

jest.setMock('someNodeLib', require('../mocks/myMockLib');
jest.dontMock('../myModuleToTest');

My expected behavior is that setMock will provide me the actual module.exports from ‘…/mocks/myMockLib’, but setMock seems to do nothing. I also tried to switch the order of the above statements, and then what ends up happening is that every require statement in the test file, no matter what module you are requiring, gets replaced with a mock of whatever setMock is defined to be.

What does work, however, is this current workaround in the test (note the order of calls):

jest.setMock('someNodeLib', require.requireActual('../mocks/myMockLib');
jest.setMock('../myModuleToTest', require.requireActual('../myModuleToTest');

All of this is a bit of a kludge, when in actuality a node_module I required, i.e. ‘request’, was not correctly mocked by jest. The proposed solution is to fix the automocking such that I don’t have to explicitly set my own mocks, or to either document what setMock does better or make it fit to what it says on the jest website.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 19 (3 by maintainers)

Most upvoted comments

I think this issue can be safely closed. The issue described here should be resolved with Jest 0.9. Previous versions were always a little bit confused about node_modules. If this problem persists for anyone I’m happy to take a closer look at this issue – please provide me with a repository that has a failure case.

A few things to keep in mind: jest.setMock will likely not work when a module has already been required as a transitive dependency:

jest.unmock('Bar');
const Bar = require('Bar'); // assume this will require Foo
jest.setMock('Foo', {…})
const Foo = require('Foo'); // Foo was already required before `setMock` was called.

It therefore is required to call APIs like setMock before all other APIs.

Manual mocks for node modules can also be created by creating a __mocks__ folder and putting a node-module-name.js file in it. To mock react, for example, you’d create a __mocks__/react.js file.

The next version of Jest will introduce a new API jest.mock('Foo', () => {moduleExports}) that gets hoisted at the top of the block, when used together with babel-jest.

Please let me know if any of this doesn’t make sense or if this is still an issue 😃