使用匹配器
- 精確匹配
toBe匹配使用===
全等匹配
test('two plus two is four', () => {
expect(2 + 2).toBe(4);
});
如果需要檢查對象或者數(shù)組需要使用toEqual
test('object assignment', () => {
const data = {one: 1};
data['two'] = 2;
expect(data).toEqual({one: 1, two: 2});
});
-
真
值匹配
- toBeNull 只匹配 null
- toBeUndefined 只匹配undefined
- toBeDefined 和 toBeUndefined 相反
- toBeTruthy 匹配任何if語句為真
- toBeFalsy 匹配任何 if 語句為假
test('null', () => {
const n = null;
expect(n).toBeNull();
expect(n).toBeDefined();
expect(n).not.toBeUndefined();
expect(n).not.toBeTruthy();
expect(n).toBeFalsy();
});
- 數(shù)字
大多數(shù)的比較數(shù)字有等價的匹配器
- toBe 等于
- toBeGreaterThan 大于
- toBeGreaterThanOrEqual 大于等于
- toBeLessThan 小于
- toBeLessThanOrEqual 小于等于
- 字符串
您可以檢查對具有toMatch
正則表達式的字符串
test('test toMatch', () => {
expect('dankun').toMatch(/^dan/)
});
- 數(shù)組和迭代器
可以通過toContain
來檢查一個數(shù)組或者迭代對象是否包含某個特定項
test('the shopping list has beer on it', () => {
const people = ['kk','jj','nb','beer'];
expect(people).toContain('beer')
});
具體使用參考https://jestjs.io/docs/zh-Hans/expect
測試異步代碼
- 回調
測試回調需要使用done
,jest會等done
回調函數(shù)執(zhí)行結束后咨堤,執(zhí)行測試
const fetchData = (callback) => {
setTimeout(() => {
callback('dankun');
}, 200)
}
test('測試異步回調', (done) => {
const callback = (data) => {
expect(data).toBe('dankun')
}
fetchData(callback);
});
- Promise
const fetchData = () => {
return new Promise((reslove, reject) => {
reslove('dankun')
})
}
test('測試異步回調', () => {
fetchData().then(data => {
expect(data).toBe('dankun')
});
});
- await
const fetchData = () => {
return new Promise((reslove, reject) => {
reslove('dankun')
})
}
test('測試異步回調', async () => {
const data = await fetchData();
expect(data).toBe('dankun')
});
初始化和清理
寫測試的時候經(jīng)常在運行測試之前做一些準備工作,在運行測試之后進行整理工作深夯。
為多次測試重復設置
如果有一些為多次測試重復設置的工作,可以使用beforeEach
和afterEach
beforeEach(() => {
console.log('start!!!')
})
afterEach(() => {
console.log('end!!!')
})
test('test demo1', () => {
expect('dankun').toMatch(/^dan/);
})
test('test demo2', () => {
expect(2).toBeLessThan(3)
})
會分別執(zhí)行兩次的start和end
console.log sum.test.js:4
start!!!
console.log sum.test.js:8
end!!!
console.log sum.test.js:4
start!!!
console.log sum.test.js:8
end!!!
一次性設置
某些情況下贿堰,只需要在文件的開頭做一次性的設置。需要使用beforeAll
,afterAll
進行處理
下面情況start
和end
只會執(zhí)行一次
beforeAll(() => {
console.log('start!!!')
})
afterAll(() => {
console.log('end!!!')
})
test('test demo1', () => {
expect('dankun').toMatch(/^dan/);
})
test('test demo2', () => {
expect(2).toBeLessThan(3)
})
作用域
默認情況下 beforeEach和afterEach是應用到文件的每個測試囱晴。但是我們可以是describe來區(qū)分測試分組。當 before 和 after 的塊在 describe 塊內部時积暖,則其只適用于該 describe 塊內的測試风喇。
test('test demo1', () => {
beforeEach(() => {
console.log('demo1 start!!!')
})
expect('dankun').toMatch(/^dan/);
})
test('test demo2', () => {
expect(2).toBeLessThan(3)
})
Mock函數(shù)
在項目中,一個模塊的方法內常常會去調用另外一個模塊的方法樊破。在單元測試中厅篓,我們可能并不需要關心內部調用的方法的執(zhí)行過程和結果,只想知道它是否被正確調用即可捶码,甚至會指定該函數(shù)的返回值。此時或链,使用Mock函數(shù)是十分有必要惫恼。
Mock函數(shù)提供的以下三種特性,在我們寫測試代碼時十分有用:
- 捕獲函數(shù)調用情況
- 設置函數(shù)返回值
- 改變函數(shù)的內部實現(xiàn)
jest.fn()
- 基本使用
jest.fn()
默認會返回undefined
作為返回值
let mockFn = jest.fn()
expect(mockFn()).toBeUndefined();
- 設置返回值
- 返回固定值
test('測試jest.fn()返回固定值', () => {
let mockFn = jest.fn().mockReturnValue('dankun')
expect(mockFn()).toBe('dankun');
})
- 內部實現(xiàn)返回某個值
test('測試jest.fn()內部實現(xiàn)', () => {
let mockFn = jest.fn((str)=> {
return str + 'test'
})
expect(mockFn('dankun_')).toBe('dankun_test');
})
- 返回Promise
test('測試jest.fn()返回Promise', async () => {
let mockFn = jest.fn().mockResolvedValue('default');
let result = await mockFn();
expect(result).toBe('default');
})
jest.mock()
比如fetch.js封裝的請求方法可能是我們在其他模塊調用時候,并不需要進行實際的請求(請求方法已經(jīng)通過單側或需要該方法返回非真實數(shù)據(jù))澳盐。此時祈纯,使用jest.mock()去mock整個模塊
是十分有必要的。
// fetch函數(shù)
const axios = require('axios');
module.exports = {
async fetchPostsList(callback) {
return axios.get('https://jsonplaceholder.typicode.com/posts').then(res => {
return callback(res.data);
})
}
}
mock的模塊
// events.js
import fetch from './fetch';
export default {
async getPostList() {
return fetch.fetchPostsList(data => {
console.log('fetchPostsList be called!');
// do something
});
}
}
在測試代碼中如下
// functions.test.js
import events from '../src/events';
import fetch from '../src/fetch';
jest.mock('../src/fetch.js');
test('mock 整個 fetch.js模塊', async () => {
expect.assertions(2);
await events.getPostList();
expect(fetch.fetchPostsList).toHaveBeenCalled();
expect(fetch.fetchPostsList).toHaveBeenCalledTimes(1);
});
mock.mockImplementation
當您需要定義從另一個模塊創(chuàng)建的模擬函數(shù)的默認實現(xiàn)時叼耙,mockImplementation方法很有用:
mock fetch模塊中的fetchPostsList
方法
jest.mock('./fetch')
const fetch = require('./fetch');
test('fetchPostsList 函數(shù)被調用', async() => {
fetch.fetchPostsList.mockImplementation(async () => {
return await Promise.resolve('dankun')
});
const result= await fetch.fetchPostsList();
console.log(result)
expect(result).toBe('dankun')
})
jest.spyOn()
jest.spyOn()方法同樣創(chuàng)建一個mock函數(shù)腕窥,但是該mock函數(shù)不僅能夠捕獲函數(shù)的調用情況,還可以正常的執(zhí)行被spy的函數(shù)筛婉。實際上簇爆,jest.spyOn()是jest.fn()的語法糖,它創(chuàng)建了一個和被spy的函數(shù)具有相同內部代碼的mock函數(shù)爽撒。