Jest 和 Enzyme 的问题
Posted
技术标签:
【中文标题】Jest 和 Enzyme 的问题【英文标题】:Issue with Jest and Enzyme 【发布时间】:2020-01-15 13:14:31 【问题描述】:我在使用 Jest 和 Enzyme 进行单元测试时遇到了一些问题。 我正在将 React 与 Typescript、情感框架一起使用。 我在按钮组件上添加了一个简单的单元测试,只是为了看看测试是否有效。
// 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":"preserve" 作为构建的 typescript 编译选项,使用 "jsx":"react" 作为 jest 的 typescript 编译选项。
// 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"
],
【问题讨论】:
【参考方案1】:有几种方法可以解决这个问题,但我们的想法是利用模拟/间谍。
1) 窥探localStorage 的原型。在github上讨论过这个问题。
jest.spyOn(window.localStorage.__proto__, 'setItem');
2) 模拟 localStorage 本身的方法。 *** 上的另一个 post 充分涵盖了它们。
【讨论】:
我尝试了所有这些,但我只测试了一个组件 -button
,它不需要 localStorage。我认为这是配置的问题。谢谢。以上是关于Jest 和 Enzyme 的问题的主要内容,如果未能解决你的问题,请参考以下文章
React / Enzyme:运行 Jest / Enzyme 测试时出现 Invariant Violation 错误
使用 Jest 和 Enzyme 测试使用 Redux 的功能性 React 组件
用 Jest 和 Enzyme 测试 React Router
异步 componentDidMount 时使用 React 的 Jest 和 Enzyme 进行测试
设置 Jest 和 Enzyme 来测试 React 15 找不到模块 react/lib/ReactTestUtils