When upgrading from [email protected] to latest the mocks are no longer picked up from /__mocks__ directory
YES
jest manual mocks broken
Environment Info:
System:
OS: macOS 10.14.5
CPU: (8) x64 Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
Binaries:
Node: 12.8.0 - /usr/local/bin/node
Yarn: 1.17.3 - ~/.yarn/bin/yarn
npm: 6.10.2 - /usr/local/bin/npm
Browsers:
Chrome: 76.0.3809.100
Firefox: 68.0.1
Safari: 12.1.1
npmPackages:
react: ^16.9.0 => 16.9.0
react-dom: ^16.9.0 => 16.9.0
react-scripts: 3.1.1 => 3.1.1
npmGlobalPackages:
create-react-app: 2.1.3
(Write your steps here:)
Mocks are picked up by jest
Mocks are not picked up
(Paste the link to an example project and exact instructions to reproduce the issue.)
To see that is works with previous react-scripts do
I can't reproduce this with 3.1.1, we have a __mocks__
folder under src/
with 2 different mocks (one of a node module and one of an internal module) and they both work
@FezVrasta __mocks__
for node modules should be located immediately next to the node_modules
directory.
https://jestjs.io/docs/en/manual-mocks#mocking-node-modules
This may have been caused by #7480.
This is problematic because __mocks__
for user modules may collide with the __mocks__
for node_modules
.
If we're not going to revert https://github.com/facebook/create-react-app/pull/7480, I feel we should at least document the new jest source since it is not standard and document the risk of collision.
@jnak even under src the mocks work just fine. I always did it that way
@jnak even under src the mocks work just fine. I always did it that way
I know they work. But it is not standard (as per the jest
documentation) and you may be running into a __mocks__
collision.
Anyway, I don't feel strongly about it. I just wanted to let you know of this undocumented gotcha.
What to do guys? Shall we just move the mocks to src folder and hope for no collisions? We only have about 3-4 projects to upgrade.
Honestly I think #7480 should be reverted, or at least just let us set the roots
config in our package.json
so we can avoid anti-patterns like this.
No pressure, but would be good to know the decision if we should move the mocks to upgrade. Thanks!
We may be able to specify __mocks__
living in the project root as another entry in the roots
configuration. If someone has time could they try this? This may be a good solution to keep the performance benefits of #7480 and supporting the __mocks__
next to node_modules
convention.
@ianschmitz I've tried adding the project root to the roots
configuration in package.json
, but CRA threw an error saying that it wasn't supported and didn't run my tests at all.
Correct - we don't support modifying roots
. What you'll have to do test this is edit the createJestConfig.js
file in node_modules/react-scripts
as was done here: https://github.com/facebook/create-react-app/pull/7480/files#diff-40a56a7d41499eab85303b5e977f9742.
Try something like:
{
roots: ['<rootDir>/src', '<rootDir>/__mocks__'],
...
}
I'm working on a PR for this to add '<rootDir>/__mocks__'
to roots
.
The watcher used by Jest (jest-haste-map
> './lib/FSEventsWatcher.js'
> walker
) will throw an error if '<rootDir>/__mocks__'
doesn't exist.
I assume we want to use heuristics to check if the directory exists and push it onto roots if it does?
Would this be the correct way to check for the directory?
const nodeMocksRootPath = path.join(rootDir || paths.appPath, '__mocks__');
const nodeMocksRootStats =
fs.existsSync(nodeMocksRootPath) && fs.statSync(nodeMocksRootPath);
if (nodeMocksRootStats && nodeMocksRootStats.isDirectory()) {
roots.push('<rootDir>/__mocks__');
}
rootDir
is used in the _test_ script and is set to the _template_ directory. It's not used in the _eject_ script, is paths.appPath
the correct value to use then?
For those whose test's are completely broken by this:
Moving __mocks__
under ./src
solved the problem for me.
@brendanmc6 the issue is this is an anti-pattern.
The Jest documentation says that any external module manual mocks must live in the same level as node_modules
, see https://jestjs.io/docs/en/manual-mocks#mocking-node-modules
As a temporary solution, I moved __mocks__ to /src folder. But this is kind of very annoying bug, which blocks a very useful feature of Jest. As an example, I do want to mock Axios only once in my code for the whole project and it will be nice if it could be done according to Jest documentation.
Strangely this happened to me in two other projects as well, a Next.JS and a React Native project, both times because my CI was failing (local tests were passing). In both cases moving it to a subfolder other than root solved the problem. Just leaving this here for the paper trail-- I can't seem to find any other issues listed anywhere.
Can this be fixed soon, I can't mock node_modules as per jest documentation.
Hi @KennethSundqvist, how's it going with your proposed fix?
@brendanmc6 Thanks! spent about three hours to figure this out.
Is there any progress with the PR for this issue fix? This feature is quite helpful for my testing
still no fix? :/ This is also not working on React Native 0.62
I spent a lot of time today trying to figure out what I was doing wrong while following the jest module mock documentation very closely. Ideally CRA templates that use jest should contain the same defaults as plain-old-jest since react documentation directs newbies to use CRA.
Learning Create React App and trying to follow TDD, it is very frustrating to have spent two days doubting myself what I have done wrong only to find out it is due to a downstream change and that the patch to fix it has stagnated for more than half a year. If the fix is not making it in anytime soon, could you please at least leave a note in the documentation?
Most helpful comment
@brendanmc6 the issue is this is an anti-pattern.
The Jest documentation says that any external module manual mocks must live in the same level as
node_modules
, see https://jestjs.io/docs/en/manual-mocks#mocking-node-modules