We just recently did a React Native
upgrade to 0.72.4
on our project and therefore updated the versions of the testing libraries as well. These are the versions they're at right now:
Relevant dependencies:
"jest-environment-jsdom": "29.7.0",
"jest-expo": "49.0.0",
Relevant dev dependencies:
"@testing-library/jest-native": "5.4.3",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "12.3.0",
"jest": "29.7.0",
"ts-jest": "29.1.1",
Our jest.config.js
looks like this:
module.exports = {
testEnvironment: 'node',
setupFiles: [
'./jest.setup.js',
'./node_modules/react-native-gesture-handler/jestSetup.js',
'./node_modules/react-native/jest/setup.js',
'./node_modules/react-native/Libraries/Utilities/__mocks__/BackHandler.js',
],
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
tsconfig: 'tsconfig.jest.json',
babelConfig: true,
diagnostics: {
exclude: ['**'],
},
},
],
},
preset: 'jest-expo',
setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
moduleFileExtensions: ['js', 'json', 'node', 'ts', 'tsx'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/assetsTransformer.js',
'\\.(css|less)$': '/assetsTransformer.js',
'\\.svg': '<rootDir>/__mocks__/svgMocks.js',
'uuid': require.resolve('uuid'),
},
transformIgnorePatterns: [
'node_modules/(?!(jest-)?@react-native|react-native|@react-native-community|@react-navigation|expo(nent)?|@expo(nent)?/.*)',
],
roots: ['<rootDir>/__mocks__', '<rootDir>/src'],
collectCoverageFrom: [
'!src/core/**/**.js',
'!src/api',
'!src/constants',
'!src/navigation',
'!node_modules/',
'!src/index.js',
'src/**/*.{js,jsx,ts,tsx}',
'!src/**/stories.{js,jsx,ts,tsx}',
'!src/**/styles.{js,jsx,ts,tsx}',
'!src/**/types.{js,jsx,ts,tsx}',
],
coverageThreshold: {
global: {
branches: 30,
functions: 30,
lines: 30,
statements: 30,
},
},
};
We do have a custom render wrapper function that looks like this:
import React, { ReactElement } from 'react';
import { render, act } from '@testing-library/react-native';
import configureStore from 'redux-mock-store';
import AppProviders from 'core/providers';
import { RootState } from 'core/store';
type Props = {
initialState?: Partial<RootState>;
hideGlobalConfirm?: boolean;
mockStore?: boolean;
};
const middlewares: any = [];
const mockStore = configureStore(middlewares);
const customRender = (ui: ReactElement, options?: Omit<any, 'queries'> & Props) =>
render(ui, {
wrapper: ({ children }) => {
if (options?.mockStore) {
const store = mockStore(options?.initialState);
return (
<AppProviders store={store} hideGlobalConfirm={options?.hideGlobalConfirm}>
{children}
</AppProviders>
);
}
return (
<AppProviders initialState={options?.initialState as any} hideGlobalConfirm={options?.hideGlobalConfirm}>
{children}
</AppProviders>
);
},
...options,
});
export async function wait(ms = 1000) {
await act(async () => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
});
}
export * from '@testing-library/react-native';
export { customRender };
The problem is that the tests fail at random with the error 'render' method has not been called
. And it's a different test each time. An example of a test that fails is:
describe('renders correctly', () => {
it('should be able to render - default', async () => {
const wrapper = customRender(renderComponent());
const myComponent = await wrapper.findByTestId('myComponent');
expect(myComponent).toBeDefined();
expect(wrapper.toJSON()).toMatchSnapshot();
});
});
Any idea what might be happening here? The tests were working fine before we did the upgrade.