Jest为所有node_modules导入返回空对象



这是我的jest配置

const {defaults: tsjPreset} = require('ts-jest/presets');
const {pathsToModuleNameMapper} = require('ts-jest');
/**
* This will fail if the tsconfig is not properly formatted as json
* use this to format it correctly
* https://jsonformatter.org/json-parser
*/
const {compilerOptions} = require('./tsconfig.json');
module.exports = {
...tsjPreset,
preset: 'react-native',
modulePathIgnorePatterns: ['<rootDir>/assets'],
/**
* required so that ts-jest can identify aliases as mentioned in tsconfig
* https://kulshekhar.github.io/ts-jest/docs/getting-started/paths-mapping/
*/
modulePaths: [compilerOptions.baseUrl],
/**
* using module name mapper to:
* - expose the alias paths to ts-jest from tsconfig (babel-jest seems to read it automatically from babel config)
* Note that the baseUrl alias is handled above by modulePaths
* - replace assets imports with a mock implementation
* https://jestjs.io/docs/29.2/webpack
* Note that the order of rules is important, as the first matched rule is applied.
* We want to make sure that files with below extensions are matched by the first rule and get mocked using fileMock.js
*/
moduleNameMapper: {
'\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
...pathsToModuleNameMapper(compilerOptions.paths, {
prefix: '<rootDir>/app',
}),
},
setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
/**
* by default jest does not trasnform node_modules, so if we are consuming any source code from node_modules
* we need to add it here so that jest can transpile it before consuming
*
* It seems there are a lot of react-native libraries which need to be transpiled as well,
* as they contain some or the other files which are not build output
*
* Note that adding multiple rules in the array as separate entries does not seem to work as expected
*/
transformIgnorePatterns: [
'node_modules/(?!(@react-native|react-native|@react-native-firebase)/)',
],
/**
* we need ts-jest for transforming typescript files
*/
transform: {
'^.+\.jsx$': 'babel-jest',
'^.+\.tsx?$': [
'ts-jest',
{
tsconfig: 'tsconfig.spec.json',
},
],
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

当我为以下组件编写测试时:

import React from 'react';
import LinearGradient from 'react-native-linear-gradient';
import {useAppTheme} from '@util/hookUtils';
import {StyleSheet} from 'react-native';
const ScrollOverflow = (): JSX.Element => {
const theme = useAppTheme();
const colors = theme.isDark
? [theme.secondaryDarkColor, theme.secondaryColor]
: [theme.primaryDarkColor, theme.primaryColor];
return <LinearGradient style={styles.scrollOverview} colors={colors} />;
};
export default ScrollOverflow;

我得到一个错误的玩笑说:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `ScrollOverflow`.

当我使用断点调试时,我可以看到react-native-linear-gradient被导入为:

react-native-linear-graident1: { default: {} };

而我的本地组件以非空默认值导入并且正常工作。

对于我从node_modules加载的任何其他组件都会发生这种情况,例如react-native-modal

我相信这与jest转换或不转换node_modules有关,但我无法通过更改jest配置中的各种参数(如transformignorepatterns和其他参数)使其工作。

指针吗?

在进一步调试之后,我意识到发生这种情况是因为其他人已经使用jest.mock('react-native-modal')为这些模块创建了全局模拟

这不是立即清楚,因为全局模拟在本地测试文件中是不可见的,除非您已经知道全局模拟存在。

我能够通过添加断点进行调试,然后进入jest模块解析,它将此解析为模拟。这时我意识到这个模块可能已经被嘲笑了。

相关内容

  • 没有找到相关文章

最新更新