10-Jest&Enzyme執(zhí)行單元測試

React開發(fā)中要進行單測,主要是針對UI層的 React Components 和業(yè)務(wù)流程的 Redux Saga來進行。

Jest 簡介

Jest 是由facebook提供的一個開源 Javascript 測試框架,由于和 React 同出一源,所以能很好的和 React 程序結(jié)合使用。

  • Jest 是基于Jasmine 2實現(xiàn)的,所以沿用了Jasmine的Matcher,熟悉Jasmine的可以直接上手。
  • Jest 執(zhí)行環(huán)境默認是使用的Node.js 上的 jsdom,所以對于 DOM 的操作不依賴瀏覽器,通過命令行完成,因此不需要安裝任何別的測試運行環(huán)境。
  • 支持 Mock,覆蓋率,Snapshots等測試工具。
  • 優(yōu)先執(zhí)行前回出錯的測試,支持并行執(zhí)行,執(zhí)行速度很快。

Enzyme 簡介

Enzyme 是基于React原生Test Utilities的一個擴展工具包,能夠更好的幫助完成React的控件測試。提供了一套類 Jquery查詢器語法的選擇方法,對于定位Dom元素相當方便。Enzyme 也是 React 官網(wǎng)推薦的進行單測的工具,可以認為是標配了。Test Utilities

開始實現(xiàn)

安裝必要包和類型定義文件

yarn add -D jest @types/jest enzyme enzyme-adapter-react-16 @types/enzyme @types/enzyme-adapter-react-16

這里的 enzyme-adapter-react-16 包是為了建立 React 和 enzyme的一個適配器。

接著我們在根目錄創(chuàng)建 jest.config.js 的 Jest 配置文件。

module.exports = {
    // 設(shè)置jsdom運行環(huán)境的URL
    // 默認值:: http://localhost
    testURL: 'http://localhost/',
    // glob模式指定查找測試文件的規(guī)則
    // 默認值:: [ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ]
    testMatch: [
        '<rootDir>/**/__tests__/**/*.{js,jsx,ts,tsx}',
        '<rootDir>/**/*.{spec,test}.{js,jsx,ts,tsx}',
    ],
    // 項目模塊中使用的文件擴展名數(shù)組
    // 默認值:: ["js", "json", "jsx", "ts", "tsx", "node"]
    // 因為是從左到右尋找,推薦將自項目常用的文件擴展名排在前面
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
    // 每個測試文件運行前執(zhí)行指定代碼配置或者是創(chuàng)建測試環(huán)境
    // 默認值:[]
    setupFiles: [
        '<rootDir>/__test__/test.setup.ts',
    ],
    // 指定測試環(huán)境
    // 默認值︰"jsdom",這里是指jsdom11
    // 可以安裝自定義的測試環(huán)境,來指定對應(yīng)的jsdom版本,例如jest-environment-jsdom-fourteen
    testEnvironment: 'jsdom',
    // 指定模塊的搜索路徑
    // 默認值:[]
    modulePaths: ['<rootDir>/src/'],
    // 允許使用一個簡單的module,來替換類似圖片,樣式類的資源
    // 默認值︰null
    moduleNameMapper: {}
};

Jest 的配置相當豐富,你可以通過一個簡單的配置擴展自己的實際項目需求,具體配置請參照官方文檔 Configuring Jest

完成配置后,在根目錄新建如下項目結(jié)構(gòu)

__test__
├─ components/
└─ sagas/
 test.setup.ts

如上面配置所示,test.setup.ts完成了再運行測試之前,對于 Enzyme 的配置啟動。

test.setup.ts

/* eslint-disable import/no-unresolved */
import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";

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

我們分別針對組件 Headernovel的saga業(yè)務(wù)流程增加單元測試。

Header.spec.tsx

/* eslint-disable import/no-unresolved */
import React from "react";
import { shallow } from "enzyme";

import Header from "../../src/components/Header";

describe("<Header />", () => {
  it("renders four li tag", () => {
    const wrapper = shallow(<Header />);
    expect(wrapper.find("ul Link")).toHaveLength(4);
  });
});

novel.spec.ts

import { watchSearchNovels } from "../../src/sagas/novel";
import { take, call } from "redux-saga/effects";
import { fetchNovels } from "../../src/actions/novel";
import { queryNovels } from "../../src/services/novelapi";

test("watchSearchNovels Saga test", () => {
  const gen = watchSearchNovels();

  expect(gen.next().value).toEqual(take(fetchNovels));
  expect(gen.next().value).toEqual(call(queryNovels));
});

以上演示的只是簡單應(yīng)用,對于復(fù)雜的測試可能需要增加Mock操作或者引入其他工具插件,后續(xù)會陸續(xù)記錄追加。

最后我們修改package.json,增加對應(yīng)的執(zhí)行命令。

"scripts": {
    "build": "webpack --config webpack.prod.js",
    "build_dev": "webpack --config webpack.dev.js",
    "dev": "webpack-dev-server --open --config webpack.dev.js",
    "mock": "node ./src/mock/mock-server.js",
    "test": "jest",
    "test_dev": "jest --coverage"
  },

執(zhí)行yarn test

單測執(zhí)行結(jié)果

如此我們可以愉快的開始寫單體測試代碼了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容