使用Jest測試JavaScript (入門篇)
1 什麼是 Jest?
Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所需要的所有測試工具,是一款幾乎零配置的測試框架。並且它對同樣是 Facebook 的開源前端框架 React 的測試十分友好。
2 安裝Jest
2.1 初始化package.json
在shell
中輸入以下命令,初始化前端專案並生成package.json
:
npm init -y
2.2 安裝Jest及相關依賴
在shell
中輸入以下命令,安裝測試所需要的依賴:
npm install -D jest babel-jest babel-core babel-preset-env regenerator-runtime
babel-jest
、 babel-core
、 regenerator-runtime
、babel-preset-env
這幾個依賴是為了讓我們可以使用ES6的語法特性進行單元測試,ES6提供的 import
來匯入模組的方式,Jest本身是不支援的。
2.3 新增.babelrc
檔案
在專案的根目錄下新增.babelrc
檔案,並在檔案複製如下內容:
{
"presets": ["env"]
}
```
2.4 修改package.json
中的test
指令碼
開啟package.json
檔案,將script
下的test
的值修改為jest
:
"scripts": { "test": "jest" }
3. 編寫你的第一個Jest測試
建立src
和test
目錄及相關檔案
- 在專案根目錄下建立
src
目錄,並在src
目錄下新增functions.js
檔案 - 在專案根目錄下建立
test
目錄,並在test
目錄下建立functions.test.js
檔案
Jest會自動找到專案中所有使用.spec.js
或.test.js
檔案命名的測試檔案並執行,通常我們在編寫測試檔案時遵循的命名規範:測試檔案的檔名 = 被測試模組名 + .test.js
,例如被測試模組為functions.js
,那麼對應的測試檔案命名為functions.test.js
。
在src/functions.js
export default {
sum(a, b) {
return a + b;
}
}
在test/functions.test.js
檔案中建立測試用例
import functions from '../src/functions';
test('sum(2 + 2) 等於 4', () => {
expect(functions.sum(2, 2)).toBe(4);
})
執行npm run test
, Jest會在shell
中打印出以下訊息:
PASS test/functions.test.js
√ sum(2 + 2) 等於 4 (7ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 4.8s
4.常用的幾個Jest斷言
上面測試用例中的expect(functions.sum(2, 2)).toBe(4)
為一句斷言,Jest為我們提供了expect
函式用來包裝被測試的方法並返回一個物件,該物件中包含一系列的匹配器來讓我們更方便的進行斷言,上面的toBe
函式即為一個匹配器。我們來介紹幾種常用的Jest斷言,其中會涉及多個匹配器。
.not
//functions.test.js
import functions from '../src/functions'
test('sum(2, 2) 不等於 5', () => {
expect(functions.sum(2, 2)).not.toBe(5);
})
.not
修飾符允許你測試結果不等於某個值的情況,這和英語的語法幾乎完全一樣,很好理解。
.toEqual()
// functions.js
export default {
getAuthor() {
return {
name: 'LITANGHUI',
age: 24,
}
}
}
// functions.test.js
import functions from '../src/functions';
test('getAuthor()返回的物件深度相等', () => {
expect(functions.getAuthor()).toEqual(functions.getAuthor());
})
test('getAuthor()返回的物件記憶體地址不同', () => {
expect(functions.getAuthor()).not.toBe(functions.getAuthor());
})
.toEqual
匹配器會遞迴的檢查物件所有屬性和屬性值是否相等,所以如果要進行應用型別的比較時,請使用.toEqual
匹配器而不是.toBe
。
.toHaveLength
// functions.js
export default {
getIntArray(num) {
if (!Number.isInteger(num)) {
throw Error('"getIntArray"只接受整數型別的引數');
}
let result = [];
for (let i = 0, len = num; i < len; i++) {
result.push(i);
}
return result;
}
}
// functions.test.js
import functions from '../src/functions';
test('getIntArray(3)返回的陣列長度應該為3', () => {
expect(functions.getIntArray(3)).toHaveLength(3);
})
.toHaveLength
可以很方便的用來測試字串和陣列型別的長度是否滿足預期。
.toThrow
// functions.test.js
import functions from '../src/functions';
test('getIntArray(3.3)應該丟擲錯誤', () => {
function getIntArrayWrapFn() {
functions.getIntArray(3.3);
}
expect(getIntArrayWrapFn).toThrow('"getIntArray"只接受整數型別的引數');
})
.toThorw
可能夠讓我們測試被測試方法是否按照預期丟擲異常,但是在使用時需要注意的是:我們必須使用一個函式將將被測試的函式做一個包裝,正如上面getIntArrayWrapFn
所做的那樣,否則會因為函式丟擲導致該斷言失敗。
.toMatch
// functions.test.js
import functions from '../src/functions';
test('getAuthor().name應該包含"li"這個姓氏', () => {
expect(functions.getAuthor().name).toMatch(/li/i);
})
.toMatch
傳入一個正則表示式,它允許我們用來進行字串型別的正則匹配。
5 測試非同步函式
安裝axios
這裡我們使用最常用的http請求庫axios
來進行請求處理
npm install axios
編寫http請求函式
我們將請求http://jsonplaceholder.typicode.com/users/1
,這是由JSONPlaceholder提供的mock請求地址
// functions.js
import axios from 'axios';
export default {
fetchUser() {
return axios.get('http://jsonplaceholder.typicode.com/users/1')
.then(res => res.data)
.catch(error => console.log(error));
}
}
// functions.test.js
import functions from '../src/functions';
test('fetchUser() 可以請求到一個含有name屬性值為Leanne Graham的物件', () => {
expect.assertions(1);
return functions.fetchUser()
.then(data => {
expect(data.name).toBe('Leanne Graham');
});
})
上面我們呼叫了expect.assertions(1)
,它能確保在非同步的測試用例中,有一個斷言會在回撥函式中被執行。這在進行非同步程式碼的測試中十分有效。
使用async
和await
精簡非同步程式碼
test('fetchUser() 可以請求到一個使用者名稱字為Leanne Graham', async () => {
expect.assertions(1);
const data = await functions.fetchUser();
expect(data.name).toBe('Leanne Graham')
})
當然我們既然安裝了Babel
,為何不使用async
和await
的語法來精簡我們的非同步測試程式碼呢? 但是別忘記都需要呼叫expect.assertions
方法
參考資料
【1】 Jest官方文件(https://jestjs.io/zh-Hans/)
【2】 Jest Crash Course - Unit Testing in JavaScript(https://www.youtube.com/watch...