在Jest和Enzyme的单元测试中,我遇到了一些问题。 我正在使用带有Typescript和Emotion Framework的React。 我在Button Component上添加了一个简单的单元测试,只是为了查看测试是否有效。
// button.test.tsx
import React from 'react'
import { shallow } from 'enzyme'
import { Button } from '../button'
describe('First React component test with Enzyme', () => {
it('renders without crashing', () => {
shallow(<Button/>);
})
})
// button.tsx
import React from 'react'
import { FunctionComponent, HTMLAttributes, ButtonHTMLAttributes } from 'react'
import { Icon } from '~/components'
import { styles } from './styles'
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
onClick?: () => any
icon?: string
color?: 'default' | 'accent' | 'accent-dark' | 'dark'
size?: 'small' | 'medium' | 'big' | 'large'
iconSize?: number
withShadow?: boolean
}
export const Button: FunctionComponent<ButtonProps> = ({
onClick,
color = 'default',
size = 'medium',
icon,
withShadow,
children,
...props
}) => (
<button
css={[
styles.base,
styles.colors[color],
styles.sizes[size],
withShadow && styles.withShadow,
]}
onClick={onClick}
{...props}
>
{icon && (
<span css={styles.icon[color === 'dark' ? 'dark' : 'default']}>
<Icon icon={icon} size={color === 'dark' ? 16 : 12} />
</span>
)}
{children}
</button>
)
错误显示如下:
● Test suite failed to run
ReferenceError: localStorage is not defined
12 |
13 | constructor() {
> 14 | this.token = localStorage.getItem('token') || null
| ^
15 |
16 | if (this.token) {
17 | this.profile = this.decodeToken(this.token)
at new UserStore (src/stores/user.ts:14:18)
at Object.<anonymous> (src/stores/index.ts:4:26)
at Object.<anonymous> (src/components/header/index.tsx:5:1)
我正在使用“ jsx”:“保留”作为构建的打字稿编译选项,并使用“ jsx”:“反应”用于开发笑话的打字稿编译选项。
// tsConfig.js
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["esnext", "dom"],
"jsx": "preserve",
"types": ["@emotion/core", "@types/node", "jest"],
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"baseUrl": "./",
"paths": {
"~/*": ["src/*"]
}
},
"presets": ["@babel/preset-env", "@babel/preset-react"],
"include": ["src"]
}
这是开玩笑的配置:
// jestConfig.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/src/**/*.test.ts?(x)', '**/?(*.)+(test).ts?(x)'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|svg|ttf|woff|woff2)$':
'<rootDir>/asset-transformer.js',
'~(.*)$': '<rootDir>/src/$1'
},
globals: {
'ts-jest': {
tsConfig: {
jsx: "react"
}
}
},
snapshotSerializers: [
"enzyme-to-json/serializer"
],
setupFiles: [
"./test-shim.js",
"./test-setup.js"
],
moduleFileExtensions: [
"ts",
"tsx",
"js",
"jsx"
],
transform: {
"^.+\\.js(x)$": "babel-jest",
"^.+\\.(ts|tsx)$": "./test-preprocessor.js"
},
testMatch: [
"**/*.test.(ts|tsx|js|jsx)"
]
}
// .babel.rc
{
"plugins": [
[
"transform-inline-environment-variables"
],
[
"babel-plugin-jsx-pragmatic",
{
"export": "jsx",
"module": "@emotion/core",
"import": "___EmotionJSX"
}
],
[
"@babel/plugin-transform-react-jsx",
{
"pragma": "___EmotionJSX",
"pragmaFrag": "React.Fragment"
}
],
[
"emotion",
{
"sourceMap": true,
"autoLabel": false,
"cssPropOptimization": true
}
],
[
"@babel/plugin-syntax-dynamic-import"
]
],
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"node": "current"
}
}
],
"@babel/preset-typescript"
],
}