代码
让我们考虑一个简略的函数,它回来一个Promise
,依据第一个参数
的值,能够解决或回绝:
export default function promiseMe(result, timeout = 1000) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (result instanceof Error || result.startsWith("Error")) {
reject(result)
} else {
resolve(result)
}
}, timeout)
})
}
当用Jest测验异步代码时,唯一要记住的是要从测验中回来Promise
,以便Jest能够
,等待它的解析或回绝。最洁净的方法是用.resolves
匹配器来做:
const successMessage = "Done.";
// with async/await
it("resolves (1)", async () => {
await expect(promiseMe(successMessage)).resolves.toEqual(successMessage);
});
// without async/await
it("resolves (2)", () => {
return expect(promiseMe(successMessage)).resolves.toEqual(successMessage);
});
假如Promise
回绝,而测验又没有预料到,Jest会陈述一个过错:
Error: expect(received).resolves.toEqual()
Received promise rejected instead of resolved
Rejected to value: [...]
可是,假如想测验Promise
回绝,并验证回绝的原因呢?
Try-catch与async/await(坏)
看起来运用try-catch
与async/await
是实现这一方针的最简略方法,由于回绝值被抛出了:
it("rejects (bad)", async () => {
try {
await promiseMe("Error");
} catch (e) {
expect(e).toEqual("Error");
}
});
可是,等等。当promiseMe
函数回来的Promise
不会被回绝,而是解决了,会发生什么?好吧,测验仍然通过,由于从来没有到达过catch块:
拜见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#promise_rejection
Try-catch与async/await(更好)
为了克服这个问题,我们能够预期实际的断语将被执行,假如它没有发生,则测验失败。
这能够用expect.assertions
很容易做到,它验证了在测验期间有一定数量的断语被调用
it("rejects (better)", async () => {
expect.assertions(1);
try {
await promiseMe("Error");
} catch (e) {
expect(e).toEqual("Error");
}
});
现在,当没有回绝时,测验失败:
Error: expect.assertions(1)
Expected one assertion to be called but received zero assertion calls.
.rejects
(最佳)
为了使代码更有表现力,能够运用.rejects
匹配器:
it("rejects (best)", async () => {
await expect(promiseMe("Error")).rejects.toEqual("Error");
});
当没有回绝时,Jest陈述一个过错:
Error: expect(received).rejects.toEqual()
Received promise resolved instead of rejected
Resolved to value: [...]
假如回绝的值是一个Error
目标,能够运用toThrow
匹配器:
it("rejects (best)", async () => {
await expect(promiseMe(new Error(errorMessage))).rejects.toThrow(errorMessage);
await expect(promiseMe(new Error(errorMessage))).rejects.toThrow(Error); // type check
await expect(promiseMe(new Error(errorMessage))).rejects.toThrow(new Error(errorMessage));
});
另请拜见
- 用Jest测验JavaScript中的异常
- Jest Vanilla JS Starter
- 在JUnit中处理异常的不同方法,该选择哪一种?