-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jest.mock() doesn't work well with NODE_PATH #3069
Comments
@DmitriiAbramov Interesting stuff would love to take a look into it and help resolve this bug. This seems to be an issue probably with jest-resolve or jest-mock. However, I'll definitely give a shot at resolving this. |
cc @wanderley who's been working on jest-resolve |
@abdulhannanali I face the same problem. Had you any success so far? Maybe we could join forces. What I found out so far:
componentRegistry Module resolved relative
componentRegistry Module resolved through NODE_PATH directory
Because the modulePath is different, the map will not recognize that the modules are the same and run the module again. As @gaearon already mentioned should the module ID be based on the absolute path. But I am not sure how that influences the resolution mechanism with haste packages. |
I can confirm #3616 fixed this. |
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. |
I am reporting what I consider to be a bug.
Originally reported in facebook/create-react-app#1271.
Some people use
NODE_PATH
to enable "absolute imports" in their codebase. For example, runningNODE_PATH=. npm test
makes every file and folder in the top-level directory available asrequire('name')
rather thanrequire('./name')
.Current behavior
This approach works fine with Jest, but the mocking behavior is a bit confusing.
jest.mock()
only works with it correctly whenjest.mock()
matches therequire
. In other words,jest.mock('./a')
will only work for files that happen torequire('./a')
but not for the ones thatrequire('a')
. Conversely,jest.mock('a')
will only work for files that dorequire('a')
but notrequire('./a')
. Since both are possible when one setsNODE_PATH
, it can be tricky to figure out what went wrong, and whyjest.mock
doesn't always work.Expected behavior
When
NODE_PATH
is used, anda
is a file or folder in that directory, bothjest.mock('a')
andjest.mock('./a')
work the same way, and mock bothrequire('a')
andrequire('./a')
calls.Repro
See that the test fails. Open
index.test.js
andindex.js
.Observe that
jest.mock('./a', () => 'goodbye, ');
only works if there's arequire('./a')
inindex.js
, andjest.mock('a', () => 'goodbye, ');
only works if there's arequire('a')
inindex.js
.I would expect that both work in both cases, and are considered equivalent, because they ultimately resolved to the same module.
What Does Node Do?
One could argue that it's intentional behavior because
./a
anda
are different paths, and Node is known to treat different paths as different modules, so Jest should do the same.However I don't think this is the case with
NODE_PATH
.With code like this:
Node will indeed execute the module twice.
However, with
NODE_PATH=.
and calls like this:Node will still execute the module just once. This means that the module ID should be based on path after resolving, and I argue that
jest.mock()
should also treat them as the same module.The text was updated successfully, but these errors were encountered: