Any test that mocks something from react-native (such as jest.mock('Dimensions'), jest.mock('Platform')) gives the error Cannot find module '*' from test/file/directory. All these tests are passing in 0.60.6 but are broken on 0.61.x.
I added the code snippet included at the bottom of the issue in a brand new 0.61.1 project and am seeing the same issue.
React Native version:
System:
OS: macOS 10.14.5
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Memory: 2.26 GB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.13.0 - ~/.nvm/versions/node/v10.13.0/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v10.13.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.4, macOS 10.14, tvOS 12.4, watchOS 5.3
Android SDK:
API Levels: 25, 27, 28
Build Tools: 27.0.3, 28.0.3
System Images: android-23 | Intel x86 Atom, android-24 | Intel x86 Atom, android-26 | Intel x86 Atom, android-28 | Google Play Intel x86 Atom
IDEs:
Android Studio: 3.3 AI-182.5107.16.33.5314842
Xcode: 10.3/10G8 - /usr/bin/xcodebuild
npmPackages:
react: 16.9.0 => 16.9.0
react-native: 0.61.1 => 0.61.1
Describe what you expected to happen:
Tests should run as they did in previous versions of RN
Snack, code example, screenshot, or link to a repository:
Create a new test file:
````js
jest.mock('Dimensions');
it('passes', () => expect(true).toBe(true));
````
It will fail with Cannot find module 'Dimensions' from ....
I had the same problem, @tomtargosz, did you use the pattern to mock the platform like this?:
const mockPlatform = (OS: 'android' | 'ios') => {
jest.resetModules()
jest.doMock('Platform', () => ({ OS, select: objs => objs[OS] }))
}
This is intentional, as the modules now need to be required like any other JS module (https://github.com/facebook/react-native/issues/26579#issuecomment-535244001).
Solution is to use the correct path, as described here:
https://github.com/facebook/react-native/issues/26579#issuecomment-535765528
So e.g
jest.mock('TextInput', () => {})
becomes
jest.mock('react-native/Libraries/Components/TextInput/TextInput', () => {})
While I'm glad there is an answer, it is fairly confusing, because now we need to understand the internal structure of the RN libraries, which feels like a step back.
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.
This is intentional, as the modules now need to be required like any other JS module (#26579 (comment)).
Solution is to use the correct path, as described here:
#26579 (comment)So e.g
jest.mock('TextInput', () => {})
becomes
jest.mock('react-native/Libraries/Components/TextInput/TextInput', () => {})
What is the Platform path @ygerg?
I had the same problem, @tomtargosz, did you use the pattern to mock the platform like this?:
const mockPlatform = (OS: 'android' | 'ios') => { jest.resetModules() jest.doMock('Platform', () => ({ OS, select: objs => objs[OS] })) }
Where I can put this @nenjamin2405?!
@lucianomlima Hi :) "react-native/Libraries/Utilities/Platform"
Thanks @VadimChiritsa! Works! <3
Sorry... it's a false positive =/
I try this on tests for Android only:
jest.doMock('react-native/Libraries/Utilities/Platform', () => ({
OS: 'android',
select: config => config.android,
}));
But if I change to ios, tests pass.
I got it mixing @nenjamin2405 solution and use real Platform path! 馃帀
describe('getHeaderTitle', () => {
const mockPlatform = OS => {
jest.resetModules();
jest.doMock('react-native/Libraries/Utilities/Platform', () => ({
OS,
select: config => config[OS],
}));
};
it('should get header title when having no custom title on Android', () => {
mockPlatform('android');
const headerTitle = getHeaderTitle();
expect(headerTitle).toMatchObject({
headerStatusBarHeight: 0, // Android should be 0 and iOS undefined
headerTransparent: true,
});
const { queryByTestId } = render(headerTitle.headerTitle());
expect(queryByTestId('header-logo')).toBeTruthy();
});
it('should get header title when having no custom title on iOS', () => {
const headerTitle = getHeaderTitle();
expect(headerTitle).toMatchObject({
headerTransparent: true,
});
const { queryByTestId } = render(headerTitle.headerTitle());
expect(queryByTestId('header-logo')).toBeTruthy();
});
});
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
Most helpful comment
While I'm glad there is an answer, it is fairly confusing, because now we need to understand the internal structure of the RN libraries, which feels like a step back.