給 React + TS 項目添加 Jest 測試


以 react + ts 的組件庫項目為例,記錄 jest 安裝配置及測試的過程。

一、安裝配置

安裝 jest

npm install jest -D

生成配置文件

npx jest --init

按照引導進行選擇后,會創建配置文件 jest.config.js,並在 package.json 中添加命令腳本 test: jest

支持 babel

要想支持 ts 和 react,都需要先支持 babel,從而在測試環境中轉換代碼

npm install babel-jest @babel/core @babel/preset-env -D
// .babelrc
{
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        }
      }
    ]
  ]
}

支持 ts

npm install @babel/preset-typescript -D
// .babelrc
{
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        }
      }
    ],
    '@babel/preset-typescript'  // 添加這個
  ]
}

支持 react

npm install @babel/preset-react -D
// .babelrc
{
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        }
      }
    ],
    '@babel/preset-typescript'  
    '@babel/preset-react' // 添加這個
  ]
}

使用 react 測試工具 enzyme

添加 enzyme

npm install enzyme enzyme-adapter-react-16 -D

項目中新建 tests/jest.setup.js 文件

// jest.setup.js

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

並在 jest.config.js 中配置

setupFiles: ['./tests/jest.setup.js']

二、快照測試

  • 使用 react-test-renderer

添加 react-test-renderer 用於快照測試

npm install react-test-renderer -D

下面給 Button 組件添加測試試一下

// components/button/__test__/index.test.js

import React from 'react';
import renderer from 'react-test-renderer';
import Button from '../Button';

describe('Button 組件', () => {
    it('正確渲染 Button 組件', () => {
        const button = renderer.create(<Button>button</Button>).toJSON();
        expect(button).toMatchSnapshot();
    });
});

執行 npm run test

可以看到有一個快照被生成了

再執行一遍 npm run test,這次沒有寫快照了,並且匹配通過了

  • 也可以用 enzyme 來進行快照測試(推薦)

添加 enzyme-to-json,用於將 enzyme 構造的 wrapper 轉變成能夠支持快照測試的格式。

npm install enzyme-to-json -D

同樣,測試一下 Button 組件

// components/button/__test__/index.test.js

import React from 'react';
import Button from '../Button';
import { render } from 'enzyme';
import toJson from 'enzyme-to-json';

describe('Button 組件', () => {
    it('正確渲染 Button 組件', () => {
        const button = render(<Button>button</Button>);
        expect(toJson(button)).toMatchSnapshot();
    });
});

執行 npm run test,沒通過,因為跟之前react-test-renderer渲染的快照不匹配了

我們需要重新寫快照,執行npx jest -u

快照更新了,再執行一下npm run test,通過了

代碼中的 toJson 部分可以統一配置到 jest.config.js,添加快照序列化配置,代碼里就不用寫 toJson 了。

snapshotSerializers: ['enzyme-to-json/serializer']

三、事件測試

利用 mock 函數 測試一下 Button 組件的事件

// components/button/__test__/index.test.js

import React from 'react';
import Button from '../Button';
import { render, mount } from 'enzyme';

describe('Button 組件', () => {
    it('正確渲染 Button 組件', () => {
        const button = render(<Button>button</Button>);
        expect(button).toMatchSnapshot();
    });

    it('測試 Button 組件 loading 參數', () => {
        const fn = jest.fn();
        const loadingButton = mount(
            <Button loading onClick={fn}>
                loading button
            </Button>
        );
        expect(loadingButton).toMatchSnapshot();
        loadingButton.find('button').simulate('click');
        expect(fn).not.toBeCalled();
    });

    it('測試 Button 組件 disabled 參數', () => {
        const fn = jest.fn();
        const disabledButton = mount(
            <Button disabled onClick={fn}>
                disabled button
            </Button>
        );
        expect(disabledButton).toMatchSnapshot();
        disabledButton.find('button').simulate('click');
        expect(fn).not.toBeCalled();
    });

    it('測試 Button 組件 onClick 事件', () => {
        const fn = jest.fn();
        const button = mount(<Button onClick={fn}>button</Button>);
        button.find('button').simulate('click');
        expect(fn).toBeCalled();
    });
});

四、參考文檔

jest 官方文檔
npm: enzyme


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM