React-Typescript 單元測試:Jest + Enzyme

按道理說官配用起來會更舒服纔是,結果接連碰壁,加上雷同狀況的資料確實有點少,只能填一下。css

0. 目前遇到的問題

首先腳手架確定不是cracra用戶請直接用官方封裝的測試就行),咱們確定會使用本身定製的腳手架。當咱們在選用Jest作單測時,出現了幾個問題:html

  • typescript
  • 沒法讀取 webpack
  • css-modules

第二點簡直硬傷,直接致使第三點無從下手。而鄙人又出於「不敢亂動祖傳代碼」的原則,只能往上面繼續填。react

1. 裝配 Jest

安裝

由你喜歡的方式去安裝 Jestwebpack

npm i -D jest @types/jest #or yarn
複製代碼

接着須要配置啓動方式git

// package.json
{
  ...
  "scripts": {
    "test": "jest",
    ...
  }
  ...
  "jest": {}
}
複製代碼

還有一個方法官方並無說起到(或者我沒有注意到)的方法,在你的project放置一個jest.config.js,一樣能夠配置,對package.json有潔癖的同窗適用。github

配置

-- 首先咱們須要什麼?
-- TypeScriptweb

npm i -D ts-jest #由於咱們已經用上了 TypeScript 因此不須要多裝一次
複製代碼
{
  "jest": {
    "moduleFileExtensions": [
      "ts",
      "tsx"
    ],
    "transform": {
      "^.+\\.tsx?$": "ts-jest",
    }
  }
}
複製代碼

接着,雖然把每一個組件的單測放在該組件的文件夾中顯得更清晰(cra的作法),可是咱們會更願意把全部測試用例放在test文件夾中。因此創建好test目錄,繼續加配置typescript

{
  "jest": {
    "moduleFileExtensions": [
      "ts",
      "tsx"
    ],
    "transform": {
      "^.+\\.tsx?$": "ts-jest",
    },
    "testMatch": [
      "<rootDir>/test/**/?(*.)(spec|test).ts?(x)"
    ],
  }
}
複製代碼

這樣,在相似ydjnb.test.tsx或者ydjnb.spec.ts等等等等的文件纔會被捕獲爲測試文件進行測試。npm

// ydjnb.spec.ts

test('Jest-TypeScript 嘗試運行', () => {
  expect(1+1).toBe(2) // Pass
})
複製代碼

至此,你可使用對Typescript的測試,但對於React來講還差一點。json

2. 裝配 Enzyme

這裏咱們就直接選用Enzyme了,在Jest文檔,關於Testing React Apps -- DOM Testing中,也提到是建議使用Enzyme

npm i -D enzyme @types/enzyme
複製代碼

回到ydjnb.spec.ts中,如今由於涉及到JSX因此應該更名爲*.tsx

// ydjnb.spec.tsx
import { shallow } from 'enzyme'

test('Jest-React-TypeScript 嘗試運行', () => {
  const renderer = shallow(<div>hello world</div>)
  expect(renderer.text()).toEqual('hello world')
})
複製代碼

固然shallow只是一種「淺渲染」,它只會對當前組件渲染,作斷言。通常測試除了關心數據還會關心交互,因此還會有另外兩個方法render, mount

3. 問題解決

-- 配完了!運行一下吧!
-- ERROR

其實細心一點就會發現,我上面的代碼段並無標記// Pass,並且如今你可能還回頭看了!

enzyme-adapter-react-16

因此第一個錯誤仍是很好解決的,由於你仔細看一下測試結果,Enzyme已經告訴你了。

Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To configure an adapter, you should call Enzyme.configure({ adapter: new Adapter() })before using any of Enzyme's top level APIs, where Adapter is the adaptercorresponding to the library currently being tested. For example:

import Adapter from 'enzyme-adapter-react-15';

To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

不過我知道我用的已是react-16了,跟着文檔也會提到關於react-16的解決方法。

npm i -D enzyme-adapter-react-16
複製代碼

回到ydjnb.spec.tsx中,

// ydjnb.spec.tsx
import { shallow, configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

configure({ adapter: new Adapter() })

test('Jest-React-TypeScript 嘗試運行', () => {
  const renderer = shallow(<div>hello world</div>)
  expect(renderer.text()).toEqual('hello world') // Pass
})
複製代碼

css-modules

根據Jest的文檔,加上一個庫解決問題:identity-obj-proxy

{
  "moduleNameMapper": {
    "\\.(css|scss)$": "identity-obj-proxy"
  },
  "transform": {
    ...
  },
  ...
}
複製代碼

至此,需求已經能徹底運做。

相關文章
相關標籤/搜索