用Jest测试你的React项目

2,429 阅读3分钟

本文作为学习记录,简介如何使用Jest测试typescript,如何集成enzyme测试React等。 前提node版本12.x

初始化项目

这里使用vitejs来初始化项目,比较简单快捷。不选用create-react-app主要是不想用其内置的测试工具,可以从零配置jest。

npm init @vitejs/app test-react --template react-ts

如果使用js的话,相对会简单点,就不需要配置jest对ts的支持了。

配置jest

因为使用了Typescript,首先可以先配置对Typescript的支持。

安装

yarn add -D jest @types/jest @jest/types

初始化jest

jest --init

image.png

修改下配置文件jest.config.ts如下

import {Config} from '@jest/types'

export default {
  clearMocks: true,
  testEnvironment: "jsdom",
  moduleDirectories: ['node_modules', 'src'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  }
} as Config.InitialOptions;

tsconfig.json中添加jest类型支持

{
  "compilerOptions": {
    ... 
    "types": ["vite/client", "jest"]  这里新增了jest,这样就能支持语法提示
  },
  ...
}

提供Typescript支持

这里直接使用ts-node就行,方便后面配合babel解析react。另外也可以使用ts-jset

安装

yarn add -D typescript ts-node

编写ts测试

写个简答的ts测试:index.test.ts

describe("ts测试", function() {
    test("hello", function() {
        let a = 1 + 5;
        expect(a).toBe(6)
    })
})

测试React

这里可以先用React内置的测试工具包react-dom/test-utils先测下。

jest支持React Test

这里需要借助Babel了,Jest会自动使用配置好的Babel。

安装

yarn add -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript

如果需要使用async,还要再安装配置@babel/plugin-transform-runtime

配置.babelrc

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-typescript",
    "@babel/preset-react"
  ]
}

编写一个React测试

import React from 'react'
import {render, unmountComponentAtNode} from 'react-dom'
import {act} from "react-dom/test-utils"
import App from '../src/App'

let container: HTMLDivElement | null
describe("react", function () {
  beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
  });

  afterEach(() => {
    if (container) {
      unmountComponentAtNode(container)
      document.body.removeChild(container);
      container = null;
    }
  });

  it('app', function () {
    act(() => {
      render(<App/>, container)
    })

    let header = container?.querySelector('header')
    expect(header).not.toBeNull()
  })
})

自此便能使用Jest对你的React进行简单的测试了,这里使用的都是React内置的工具,操作相对复杂些。下面介绍enzyme这个更为简单的工具。

集成enzyme

官方文档可见这里:enzyme文档 官方目前仅提供了到React16的测试adapter,针对React17可以使用@wojtekmaj/enzyme-adapter-react-17

安装

yarn add -D enzyme @wojtekmaj/enzyme-adapter-react-17 jest-enzyme @types/enzyme

配置

要在jest中使用enzyme,是需要配置下jest的初始环境的。首先要编写一个setup.js文件,然后配置到jest.config.ts中。

setup.js如下,主要是配置enzyme使用的适配器

import Enzyme from 'enzyme'
import Adaptor from '@wojtekmaj/enzyme-adapter-react-17'

Enzyme.configure({adapter: new Adaptor()})

新增jest配置如下

import {Config} from '@jest/types'

export default {
  ...
  setupFiles: ['./tests/setup.js'],
  // 这里是为了在jest中能使用jest-enzyme扩展的匹配器
  setupFilesAfterEnv: ['./node_modules/jest-enzyme/lib/index.js']
} as Config.InitialOptions;

tsconfig.json中添加jest-enzyme语法提示

{
  "compilerOptions": {
    ...
    "types": ["vite/client", "jest", "jest-enzyme"]
  },
  ...
}

写个测试demo

import React from 'react'
import { shallow } from 'enzyme'
import App from '../src/App'

describe("enzyme", function () {
  it('app', function () {
    let wrapper = shallow(<App/>)
    expect(wrapper.find("header")).toExist()
  })
})

与上面的测试一样,来判断组件中是不是有header标签,是不是简单了很多~

结语

本文简单说明了下React中的测试,很基础的内容,并没有说如何在测试中模拟各种事件,生命周期等。这些可以通过阅读React测试文档enzyme官方文档了解到。如果你除了单测以外还要进行集成测试,那你可能需要jest-puppeteer帮你完成。