首先, 像Jest 從安裝開始里面所說的那樣, 啟用babel的支持
讓我們實現(xiàn)一個從 API 獲取用戶數(shù)據(jù)并返回用戶名的模塊。
// user.js
import request from './request';
export function getUserName(userID) {
return request('/users/' + userID).then(user => user.name);
}
在上面的實現(xiàn)中,我們期望?request.js
?模塊返回一個 promise。我們鏈接一個調用來?then
?接收用戶名。
現(xiàn)在想象一個?request.js
?進入網(wǎng)絡并獲取一些用戶數(shù)據(jù)的實現(xiàn):
// request.js
const http = require('http');
export default function request(url) {
return new Promise(resolve => {
// 這是一個HTTP請求的例子, 用來從API獲取用戶信息
// This module is being mocked in __mocks__/request.js
http.get({path: url}, response => {
let data = '';
response.on('data', _data => (data += _data));
response.on('end', () => resolve(data));
});
});
}
因為我們在測試中不想去網(wǎng)絡,所以我們將?request.js
?在?__mocks__
?文件夾中為我們的模塊創(chuàng)建一個手動模擬(文件夾區(qū)分大小寫,?__MOCKS__
?將不起作用)。就像是這樣:
// __mocks__/request.js
const users = {
4: {name: 'Mark'},
5: {name: 'Paul'},
};
export default function request(url) {
return new Promise((resolve, reject) => {
const userID = parseInt(url.substr('/users/'.length), 10);
process.nextTick(() =>
users[userID]
? resolve(users[userID])
: reject({
error: 'User with ' + userID + ' not found.',
}),
);
});
}
現(xiàn)在我們就來編寫我們的異步函數(shù)的測試
// __tests__/user-test.js
jest.mock('../request');
import * as user from '../user';
//斷言必須返回一個primose
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toEqual('Mark'));
});
我們調用 ?jest.mock('../request ')
? 告訴jest 使用我們手動的創(chuàng)建的模擬數(shù)據(jù)。 ?it
?斷言的是將會返回一個Promise對象,你可以在任何時候給?expect
?打電話,只要你在最后回復一個承諾。
有一種不那么冗長的方法?resolves
?用于將已履行的 Promise 的值與任何其他匹配器一起解包。如果 Promise 被拒絕,則斷言將失敗。
it('works with resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toEqual('Paul');
});
也可以使用?async
?/?await
?語法編寫測試。以下是如何編寫與之前相同的示例:
// 使用async/await
it('works with async/await', async () => {
expect.assertions(1);
const data = await user.getUserName(4);
expect(data).toEqual('Mark');
});
// async/await 也可以和 `.resolves` 一起使用.
it('works with async/await and resolves', async () => {
expect.assertions(1);
await expect(user.getUserName(5)).resolves.toEqual('Paul');
});
要在項目中啟用 ?async
?/?await
?,請在你的?babel.config.js
?文件中安裝并啟用@babel/preset-env功能。
可以使用? .catch
? 方法處理錯誤。 請確保添加 ?expect.assertions
? 來驗證一定數(shù)量的斷言被調用。 否則一個fulfilled態(tài)的Promise 不會讓測試失敗︰
//用 Promise.catch 測試一個異步的錯誤
it('tests error with promises', () => {
expect.assertions(1);
return user.getUserName(2).catch(e =>
expect(e).toEqual({
error: 'User with 2 not found.',
}),
);
});
// Or using async/await.
it('tests error with async/await', async () => {
expect.assertions(1);
try {
await user.getUserName(1);
} catch (e) {
expect(e).toEqual({
error: 'User with 1 not found.',
});
}
});
該?.rejects
?助手的工作方式類似于?.resolves
?幫手。如果 Promise 被拒絕,則測試將自動失敗。?expect.assertions(number)
?不是必需的,但建議驗證在測試期間調用了一定數(shù)量的assertions。其實不然容易忘記?return
?/?await
?的?.resolves
? ?assertions
?。
// 用`.rejects`.來測試一個異步的錯誤
it('tests error with rejects', () => {
expect.assertions(1);
return expect(user.getUserName(3)).rejects.toEqual({
error: 'User with 3 not found.',
});
});
// 或者與async/await 一起使用 `.rejects`.
it('tests error with async/await and rejects', async () => {
expect.assertions(1);
await expect(user.getUserName(3)).rejects.toEqual({
error: 'User with 3 not found.',
});
});
此示例的代碼位于examples/async。
如果想測試計時器,例如setTimeout,請查看計時器模擬文檔。
更多建議: