Create-react-app: node_modules Mocks are not picked up by jest with latest react-scripts

Created on 15 Aug 2019  路  24Comments  路  Source: facebook/create-react-app

Describe the bug

When upgrading from [email protected] to latest the mocks are no longer picked up from /__mocks__ directory

Did you try recovering your dependencies?

YES

Which terms did you search for in User Guide?

jest manual mocks broken

Environment

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

Steps to reproduce

(Write your steps here:)

  1. create a manual mock of any node_modules package
  2. put it to __mocks__ directory
  3. run your test

Expected behavior

Mocks are picked up by jest

Actual behavior

Mocks are not picked up

Reproducible demo

(Paste the link to an example project and exact instructions to reproduce the issue.)

  1. git clone https://github.com/tomitrescak/react-boilerplate -b Demo
  2. cd react-boilerplate
  3. yarn
  4. yarn test
  5. p -> 'button'
  6. error: Trans not found (not being picked up by mocks)

To see that is works with previous react-scripts do

  1. yarn add [email protected]
  2. yarn test
  3. You will recieve a snapshot erro which is fine
up for grabs! bug

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

All 24 comments

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?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

barcher picture barcher  路  3Comments

fson picture fson  路  3Comments

Aranir picture Aranir  路  3Comments

stopachka picture stopachka  路  3Comments

xgqfrms-GitHub picture xgqfrms-GitHub  路  3Comments