Skip to content
This repository was archived by the owner on Jul 30, 2020. It is now read-only.

Cannot find module 'ReactNative' from 'mock-modules.js' with jest-expo #48

Closed
marsinearth opened this issue Aug 1, 2019 · 12 comments
Closed
Labels
help wanted Extra attention is needed released

Comments

@marsinearth
Copy link

marsinearth commented Aug 1, 2019

Relevant code or config:

// jest.config.js
const expoPreset = require('jest-expo/jest-preset');
const jestPreset = require('@testing-library/react-native/jest-preset');

module.exports = Object.assign(expoPreset, jestPreset, {
  preset: '@testing-library/react-native',
  transform: {
    '^.+\\.js$': 'babel-jest',
    '^.+\\.tsx?$': 'ts-jest',
  },
  testMatch: [
    '**/__tests__/**/*.ts?(x)',
    '**/?(*.)+(spec|test).ts?(x)',
  ],
  moduleFileExtensions: [
    'js',
    'ts',
    'tsx',
  ],
  globals: {
    'ts-jest': {
      tsConfig: {
        jsx: 'react',
      },
      diagnostics: false,
    },
  },
  modulePathIgnorePatterns: [
    '<rootDir>/build/',
    '<rootDir>/node_modules/',
    '<rootDir>/.history/',
  ],
  setupFiles: [...expoPreset.setupFiles, ...jestPreset.setupFiles, '<rootDir>/test/jestSetup.ts'], // jestSetup.ts is an empty script.
});

What you did:

I followed the installation guide and figured out that the v^33.0.2 jest-expo doesn't contain jest-preset.json as the guide indicates, but instead jest-preset.js. Anyway I imported it as const expoPreset = require('jest-expo/jest-preset'); as in the above snippet.

What happened:

then I tried to test a script, I get this:

$ node node_modules/jest/bin/jest.js src/components/screen/__tests__/Setting.test.tsx
 FAIL  src/components/screen/__tests__/Setting.test.tsx
  ● Test suite failed to run

    Cannot find module 'ReactNative' from 'mock-modules.js'

    However, Jest was able to find:
        './mock-modules.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'ts', 'tsx'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:230:17)
      at Object.<anonymous> (node_modules/@testing-library/react-native/dist/preset/mock-modules.js:18:6)

Reproduction:

https://github.com/marsinearth/native-testing-library-issue-repro

Problem description:

I think something between jest-expo and native-testing-library has been compromised by changed structure of jest-expo package.

Suggested solution:

the error log is very limited, nor I know how to access more log. perdóname.

Can you help us fix this issue by submitting a pull request?

I wish...

@bcarroll22 bcarroll22 added the help wanted Extra attention is needed label Aug 7, 2019
@bcarroll22
Copy link
Collaborator

Hello there, sorry for the delayed response.

My team and I don't use Expo, and I noticed you're using Expo 33. I'd appreciate it someone who uses Expo could help me debug this one, I'm not really sure where to start with it since I don't use Expo personally.

@jeffreyffs
Copy link
Contributor

Hey there, I just updated to RC 0.61.0 to play around with the new Fast Refresh (💯) and I am seeing the exact same error message. Should give an easy to reproduce this in a native RN environment. Let me know if you need anymore information or maybe a separate issue.

@bcarroll22
Copy link
Collaborator

After looking into this briefly, the reason is that the newer versions of React Native don't use Facebook's module system, Haste, anymore. So, when we try to un-mock the mocked modules for our included preset, it can't find the modules because they're no longer Haste modules.

I'm going to add this to the list of reasons that we need a better, community-owned jest preset. I'm starting to get really firm on this, because it creates problems all over the place. Here's a quick list of past issues and responses:

#52 (comment)
#49 (comment)
#27 (comment)
#26 (comment)

A better jest preset is necessary because it's as close as we're going to get to something like a jsdom equivalent for RN. Also, it'll prevent issues like this from coming up, because there won't be a dependency on another jest preset. If we were to revert to using the bundled react-native jest preset, it would create a suboptimal, confusing user experience when writing tests.

For this issue specifically, the best I can do is change the bundled NTL preset to no longer rely on Haste, publish it as a breaking change, and all users on RN < 0.60 will be stuck on an old version of the package. I'm not saying I can't do that, just driving the point home that at this point, this package really needs some support in creating a jest preset. This package gets downloaded and used thousands of times a week and works for the majority of users, and dropping Haste would leave all of those people stuck on an old version of the package until they can upgrade. Unless we get some help from the community, there's probably not going to be a good solution to this unfortunately 😞

@jeffreyffs
Copy link
Contributor

Thank you for taking a look and for all your hard work on this library!

Could we possibly make this change backwards compatible by doing something like:
try { jest.unmock('react-native') // or whatever the non-Haste version of this looks like? } catch { jest.unmock('ReactNative') }

I guess you would need a fallback for every component also? I'm not 100% clear on how Haste modules work. That could possibly lead to some beautiful try/catch nesting :)

I've seen the conversation of a community jest preset come up before in other repos and it definitely interests me. The required knowledge around jest and RN internals makes it an interesting challenge and the speed at which RN keeps dropping huge changes makes for a bit of a maintenance nightmare.

@jeffreyffs
Copy link
Contributor

jeffreyffs commented Aug 28, 2019

Actually looking at this commit from a few months ago: facebook/react-native@59749f5#diff-606adbd6a8c97d177b17baee5a69cdd9

We might be able to just migrate to path based and have it work for pre 0.61 and >= 0.61. I almost have it working by mocking using react-native/Libraries/Components/Picker/Picker instead of Picker for example.

Just one error left:

    TypeError: (0 , _codegenNativeComponent.default) is not a function

      at Object.<anonymous> (node_modules/react-native/Libraries/Components/TextInput/RCTInputAccessoryViewNativeComponent.js:23:17)
      at Object.<anonymous> (node_modules/react-native/Libraries/Components/TextInput/InputAccessoryView.js:17:1)

and the same for RefreshControl (even though it is included in the components you mock 🤔 )

Edit: This might be a RN issue, as I am seeing it with the default react-native preset also.

Edit 2: Hm, same test cases appears to work in a fresh project init'd with react-native@next

@jeffreyffs
Copy link
Contributor

Above seems to be an error with my project configuration, but this MR seems to solve all the other problems: #53

@shwanton
Copy link

Just tried this out and my tests are all passing 🎉

@cjjenkinson
Copy link

Also experiencing the same issue

@bcarroll22
Copy link
Collaborator

🎉 This issue has been resolved in version 4.0.9 🎉

The release is available on:

Your semantic-release bot 📦🚀

@jeffreyffs
Copy link
Contributor

Thank you!

@bcarroll22 I'm not 100% sure this solved this specific issue (as the original report was specific to expo and I am not using expo), but the error is identical so maybe it helped them out too.

@bcarroll22
Copy link
Collaborator

I believe this will have fixed it. If not it’s all good, we can re-open and try again.

Pretty sure this will fix it for the Expo folks too, because it’d be caused by the same issue. ReactNative was the first module in the library we try to import using the hastemap.

@ghost
Copy link

ghost commented Jul 28, 2020

It failed again with the same error in 6.0.0, I have to downgrade to 5.0.3 to fix the issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed released
Projects
None yet
Development

No branches or pull requests

5 participants