Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所須要的全部測試工具,是一款幾乎零配置的測試框架。而且它對一樣是 Facebook 的開源前端框架 React 的測試十分友好。前端
package.json
在shell
中輸入如下命令,初始化前端項目並生成package.json
:ios
npm init -y
在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自己是不支持的。shell
.babelrc
文件在項目的根目錄下添加.babelrc
文件,並在文件複製以下內容:npm
{ "presets": ["env"] }
package.json
中的test
腳本打開package.json
文件,將script
下的test
的值修改成jest
:json
"scripts": { "test": "jest" }
建立src
和test
目錄及相關文件axios
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
文件中建立測試用例babel
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
上面測試用例中的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
傳入一個正則表達式,它容許咱們用來進行字符串類型的正則匹配。
安裝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...