我正在编写针对Jest和Typescript的react-native测试,但是当我模拟使用export default
和export
的模块时,我遇到了问题。
我的模拟是这样的:
// test.setup.js
jest.mock('react-native-text-input-mask', () => ({
default: 'TextInputMask',
mask: () => {},
unmask: () => {},
}));
但是当测试运行时,我的代码中的jest无法使用default
引起错误:
import React, { Component } from 'react'
import { } from 'react-native'
import TextInputMask, { mask } from 'react-native-text-input-mask'
console.log(TextInputMask) // {'default': 'TextInputMask', mask: [Function]}
console.log(mask) // [Function]
export default class Comp extends Component<> {
constructor(props) {
super(props)
}
render(): JSX.Element {
return (
<TextInputMask // error in this line
mask={'[0000]'}
/>
)
}
}
测试错误:
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
如何使用default export
和export
模拟模块?
我的开玩笑配置:
// package.json
"devDependencies": {
"@types/fbemitter": "2.0.32",
"@types/jest": "21.1.1",
"@types/prop-types": "15.5.2",
"@types/react": "16.0.9",
"@types/react-intl": "2.3.2",
"@types/react-native": "0.48.9",
"@types/react-navigation": "1.0.20",
"@types/react-redux": "5.0.9",
"@types/react-test-renderer": "15.5.4",
"@types/redux-immutable-state-invariant": "2.0.2",
"@types/redux-mock-store": "0.0.11",
"@types/redux-storage": "4.0.10",
"babel-core": "6.26.0",
"babel-jest": "21.2.0",
"babel-plugin-jest-hoist": "21.2.0",
"babel-plugin-module-resolver": "2.7.1",
"babel-plugin-transform-decorators-legacy": "1.3.4",
"babel-preset-react-native": "4.0.0",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"colors": "1.1.2",
"commitizen": "2.9.6",
"cz-conventional-changelog": "2.0.0",
"enzyme": "3.0.0",
"fbemitter": "2.1.1",
"husky": "^0.14.3",
"jest": "21.2.1",
"jest-cli": "21.2.1",
"jest-serializer-enzyme": "1.0.0",
"mocha": "3.5.3",
"plop": "1.9.0",
"prettier": "1.7.3",
"react-addons-test-utils": "15.6.2",
"react-dom": "16.0.0",
"react-native-debugger-open": "0.3.12",
"react-test-renderer": "16.0.0",
"redux-devtools-extension": "2.13.2",
"redux-immutable-state-invariant": "2.1.0",
"redux-mock-store": "1.3.0",
"rimraf": "2.6.2",
"selenium-webdriver": "3.5.0",
"sinon": "4.0.0",
"standard-version": "4.2.0",
"ts-jest": "21.0.1",
"tslint": "5.7.0",
"tslint-config-prettier": "1.5.0",
"tslint-react": "3.2.0",
"typescript": "2.5.3",
"wd": "1.4.1"
},
"jest": {
"preset": "react-native",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{ts,tsx}",
"!src/**/*.test.{ts,tsx}",
"!src/**/*.d.ts",
"!build/**",
"!**/node_modules/**"
],
"coverageDirectory": "coverage",
"moduleDirectories": [
"node_modules",
"src"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__scripts__/assetsTransformer.js",
"^@animations.+\\.(json)$": "<rootDir>/__scripts__/assetsTransformer.js"
},
"moduleFileExtensions": [
"js",
"jsx",
"json",
"ts",
"tsx",
"ios.ts",
"android.ts"
],
"modulePathIgnorePatterns": [
"<rootDir>/build/"
],
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"setupFiles": [
"./__scripts__/test-setup.js"
],
"testPathIgnorePatterns": [
"<rootDir>/build/",
"<rootDir>/node_modules/"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
"^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"transformIgnorePatterns": [
"node_modules/(?!react-native|tcomb-form-native|react-navigation|lottie-react-native|jail-monkey|redux-persist/es/storage)"
],
"globals": {
"ts-jest": {
"useBabelrc": true
}
}
},
我的TS配置:
// tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "es2015",
"jsx": "react-native",
"watch": true,
"allowJs": true,
"sourceMap": true,
"preserveConstEnums": true,
"removeComments": true,
"lib": [
"dom",
"es2017"
],
"diagnostics": false,
"noImplicitAny": false,
"noImplicitUseStrict": false,
"strictNullChecks": false,
"noImplicitThis": false,
"moduleResolution": "node",
"outDir": "./build",
"rootDir": "./src",
"sourceRoot": ".",
"baseUrl": "./src",
"typeRoots": [
"./src/types"
],
"paths": {
"@assets/*": [
"../assets/*"
],
"@animations/*": [
"../animations/*"
]
},
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true
},
"types": [
"react",
"react-native",
"jest"
],
"include": [
"src/**/*"
],
"exclude": [
"index.android.js",
"index.ios.js",
"build",
"app",
"node_modules"
],
"compileOnSave": true
}
答案 0 :(得分:0)
我解决了这个问题,为组件创建了一个模拟器,如下所示:
// __mocks__/react-native-text-input-mask.tsx
import React from 'react'
class TextInputMask extends React.Component {
render() {
return null
}
}
const mask = (mask: string, value: string, text: string => {} ) => {}
const unmask = (mask: string, masked: string, unmasked: string => {} ) => {}
const setMask = (node: any, mask: string) => {}
export { mask, unmask, setMask }
export default TextInputMask