我对 ts-jest 的 React Navigation 测试失败并显示错误:
yarn run v1.22.10
$ jest
FAIL __tests__/App.spec.tsx
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/home/rct/cod/rn-testing-issue-github-example/node_modules/react-native-iphone-x-helper/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { Dimensions, Platform, StatusBar } from 'react-native';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (node_modules/@react-navigation/bottom-tabs/lib/commonjs/views/SafeAreaProviderCompat.tsx:7:1)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.901 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
该应用程序在模拟器中按预期工作,但我无法运行测试。显然,某种 CommonJS/ESM 配置不兼容超出了我的工资等级,但在学习了六个不同的教程后,我一直无法解决它:(
欢迎所有想法!
同样的问题发布在 in React Navigation issue tracker。
重现:
git clone https://github.com/githorse/rn-testing-issue-example.git
cd rn-testing-issue-example
yarn test
App.tsx (复制自React Navigation docs):
// App.tsx
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
App.spec.tsx:
// __tests__/App.spec.tsx
import 'react-native';
import React from 'react';
import App from '../App';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
jest.useFakeTimers();
it('renders correctly', () => {
renderer.create(<App />);
});
babel.config.js 来自 ts-jest React Native docs:
// babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
}
jest.config.js 来自 ts-jest React Native docs,添加引用 setupFiles
的 jest.setup.js
键:
// jest.config.js
const { defaults: tsjPreset } = require('ts-jest/presets')
module.exports = {
...tsjPreset,
preset: 'react-native',
transform: {
...tsjPreset.transform,
'\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js',
},
globals: {
'ts-jest': {
babelConfig: true,
},
},
// This is the only part which you can keep
// from the above linked tutorial's config:
cacheDirectory: '.jest/cache',
setupFiles: [
'<rootDir>/setup.jest.js'
]
}
setup.jest.js 来自 React Native Mocking Native Modules example,注释掉产生另一个(可能不相关)错误的行:
// setup.jest.js
import 'react-native-gesture-handler/jestSetup';
// import { cleanup } from '@testing-library/react-native';
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
// The mock for `call` immediately calls the callback which is incorrect
// So we override it with a no-op
Reanimated.default.call = () => {};
return Reanimated;
});
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
// jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
// As of react-native@0.64.X file has moved
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');