按道理說官配用起來會更舒服才是,結果接連碰壁,加上雷同情況的資料確實有點少,只能填一下。
0. 目前遇到的問題
首先腳手架肯定不是cra
(cra
使用者請直接用官方封裝的測試就行),我們肯定會使用自己定製的腳手架。當我們在選用Jest
做單測時,出現了幾個問題:
typescript
- 無法讀取
webpack
css-modules
第二點簡直硬傷,直接導致第三點無從下手。而鄙人又出於“不敢亂動祖傳程式碼”的原則,只能往上面繼續填。
1. 裝配 Jest
安裝
由你喜歡的方式去安裝 Jest
npm i -D jest @types/jest #or yarn
複製程式碼
接著需要配置啟動方式
// package.json
{
...
"scripts": {
"test": "jest",
...
}
...
"jest": {}
}
複製程式碼
還有一個方法官方並沒有提及到(或者我沒有注意到)的方法,在你的project
放置一個jest.config.js
,同樣可以配置,對package.json
有潔癖的同學適用。
配置
-- 首先我們需要什麼?
-- TypeScript
!
npm i -D ts-jest #因為我們已經用上了 TypeScript 所以不需要多裝一次
複製程式碼
{
"jest": {
"moduleFileExtensions": [
"ts",
"tsx"
],
"transform": {
"^.+\\.tsx?$": "ts-jest",
}
}
}
複製程式碼
接著,雖然把每個元件的單測放在該元件的資料夾中顯得更清晰(cra
的做法),但是我們會更願意把所有測試用例放在test
資料夾中。所以建立好test
目錄,繼續加配置
{
"jest": {
"moduleFileExtensions": [
"ts",
"tsx"
],
"transform": {
"^.+\\.tsx?$": "ts-jest",
},
"testMatch": [
"<rootDir>/test/**/?(*.)(spec|test).ts?(x)"
],
}
}
複製程式碼
這樣,在類似ydjnb.test.tsx
或者ydjnb.spec.ts
等等等等的檔案才會被捕獲為測試檔案進行測試。
// ydjnb.spec.ts
test('Jest-TypeScript 嘗試執行', () => {
expect(1+1).toBe(2) // Pass
})
複製程式碼
至此,你可以使用對Typescript
的測試,但對於React
來說還差一點。
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, whereAdapter
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": {
...
},
...
}
複製程式碼
至此,需求已經能完全運作。