jest icon indicating copy to clipboard operation
jest copied to clipboard

Manual mock in nested directory mocks a package in node_modules

Open niekert opened this issue 7 years ago • 9 comments

Do you want to request a feature or report a bug? Bug

What is the current behavior? I have defined a manual mock in a nested directory (for example, src/utils/left-pad.js). I added a mock for this file in the src/utils/__mocks__/left-pad.js directory.

When I explicitly tell jest to use this mock in my tests using jest.mock('src/utils/left-pad.js') everything works fine and the mock is used when I import from 'utils/left-pad.js'

However, when I don't specify jest.mock(...) in my tests, the left-pad mock is being resolved when I directly import the left-pad module from node_modules. This causes import leftPad from 'left-pad' to resolve the left pad mock.

I created a small git repo to reproduce the issue. Simply run yarn install && yarn test. https://github.com/niekert/jest-manual-mock-issue

What is the expected behavior? When I call import leftPad from 'left-pad', the module is resolved from node_modules instead of from the src/utils/__mocks/left-pad.js file.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

[email protected]
[email protected]
[email protected]
[email protected]
MacOS Sierra 10.12.5

niekert avatar Jun 23 '17 08:06 niekert

Read the docs on manual mocking, this is how it works for regular node modules. Use jest.unmock(path/to/module) to change the default behavior

thymikee avatar Jun 23 '17 10:06 thymikee

The docs state the following:

If the module you are mocking is a node module (eg: fs), the mock should be placed in the mocks directory adjacent to node_modules.

My mock is placed in a nested directory, so not adjacent to the node_modules folder. Because of that I was confused that jest that is still mocking the package from node_modules. I understand that changing this behaviour now would break a lot of tests, but I'm curious if there's any reason as to why it works like this :)

Maybe explicitly mentioning this in the docs could be helpful for future visitors? I'd be happy to create a PR for that.

jest.unmock does indeed solve this, so thanks for that!

niekert avatar Jun 23 '17 12:06 niekert

Oh, that's what happens. I'm not sure if that's possible to change now (I'm aware that manual mocking is kinda broken in some places), maybe @aaronabramov will know more.

thymikee avatar Jun 23 '17 12:06 thymikee

i don't know much about how mocking works right now, but i encountered a few issues like this already. i'll be working on mocking system next quarter and will look into it. (yeah, we should fix it asap)

aaronabramov avatar Jun 23 '17 19:06 aaronabramov

@niekert we now mention this in docs as official way of how things work: https://github.com/facebook/jest/pull/5616, but it's still a bug and should be resolved.

thymikee avatar Feb 19 '18 21:02 thymikee

The bug is still there and documentation doesn't mention that lodash will be mocked by lodash.js in any __mocks__ folder.

alexeyten avatar Nov 13 '19 14:11 alexeyten

I have a similar, more contrived example where axios is mocked even though the folder structure is like this:

WidgetA/
WidgetA/__mocks__
WidgetA/__mocks__/axios.js
WidgetA/WidgetA.js
WidgetA/WidgetA.test.js
WidgetB/
WidgetB/WidgetB.js
WidgetB/WidgetB.test.js

If I ask jest to only run WidgetB.test.js, the mock is still imported and set up. So there are two errors here: (1) it was imported in the first place (2) it is being set up automatically (yes - I have verified that automocks is set to false).

mzedeler avatar Apr 30 '20 13:04 mzedeler

Same issue as @mzedeler with [email protected]

I have a similar, more contrived example where axios is mocked even though the folder structure is like this:

WidgetA/
WidgetA/__mocks__
WidgetA/__mocks__/axios.js
WidgetA/WidgetA.js
WidgetA/WidgetA.test.js
WidgetB/
WidgetB/WidgetB.js
WidgetB/WidgetB.test.js

If I ask jest to only run WidgetB.test.js, the mock is still imported and set up. So there are two errors here: (1) it was imported in the first place (2) it is being set up automatically (yes - I have verified that automocks is set to false).

testacode avatar Jun 05 '21 00:06 testacode

@thymikee is there any active work going on right now? I still encounter this, feels kind of weird behaviour

fellnerse avatar Aug 09 '22 11:08 fellnerse

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Aug 09 '23 12:08 github-actions[bot]

This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.

github-actions[bot] avatar Sep 08 '23 12:09 github-actions[bot]

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

github-actions[bot] avatar Oct 09 '23 00:10 github-actions[bot]