异步示例
非官方测试版翻译
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
首先,按照入门指南中的说明,在 Jest 中启用 Babel 支持。
让我们实现一个模块,用于从 API 获取用户数据并返回用户名。
user.js
import request from './request';
export function getUserName(userID) {
return request(`/users/${userID}`).then(user => user.name);
}
在上述实现中,我们预期 request.js 模块会返回一个 Promise。我们通过链式调用 then 来接收用户名。
现在假设 request.js 的实现需要访问网络来获取用户数据:
request.js
const http = require('http');
export default function request(url) {
return new Promise(resolve => {
// This is an example of an http request, for example to fetch
// user data from an 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));
});
});
}
由于我们不希望在测试中访问网络,将在 __mocks__ 目录 中为 request.js 创建手动模拟(注意:目录名称区分大小写,__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.slice('/users/'.length), 10);
process.nextTick(() =>
users[userID]
? resolve(users[userID])
: reject({
error: `User with ${userID} not found.`,
}),
);
});
}
现在让我们为异步功能编写测试。
__tests__/user-test.js
jest.mock('../request');
import * as user from '../user';
// The assertion for a promise must be returned.
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toBe('Mark'));
});
通过调用 jest.mock('../request') 告知 Jest 使用手动模拟。it 需要返回一个将被解析的 Promise。你可以链式调用任意数量的 Promise 并随时使用 expect,只要最终返回一个 Promise。
.resolves
可使用更简洁的 resolves 解包已兑现的 Promise 值,并配合其他匹配器使用。若 Promise 被拒绝,断言将失败。
it('works with resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toBe('Paul');
});
async/await
同样可以使用 async/await 语法编写测试。以下是先前示例的等效写法:
// async/await can be used.
it('works with async/await', async () => {
expect.assertions(1);
const data = await user.getUserName(4);
expect(data).toBe('Mark');
});
// async/await can also be used with `.resolves`.
it('works with async/await and resolves', async () => {
expect.assertions(1);
await expect(user.getUserName(5)).resolves.toBe('Paul');
});
要在项目中启用 async/await,请安装 @babel/preset-env 并在 babel.config.js 文件中启用该功能。