用Jest测试JavaScript中的异常
代码
让我们考虑一个简单的函数,它检查两个密码是否相等,当第一个密码没有被提供时,它会抛出一个错误。
export default function samePasswordsValidator(password, otherPassword) {
if (!password) {
throw new Error("no password given");
}
return password === otherPassword;
}
Try-catch习惯法(坏)。
当测试抛出异常的代码时,人们立即想到在测试代码中使用try-catch
这个成语。
it('throws an error when first argument is `null`', () => {
try {
samePasswordsValidator(null, "bar");
} catch (error) {
expect(error.message).toBe("no password given");
}
});
一般来说,这不是最好的方法。当第一个参数是null
,如预期的那样,测试就会通过。但是当代码即将改变,异常不再被抛出时,测试仍然通过。所以,代码的改变不会被测试发现。
Try-catch习惯法(更好)。
为了克服这个问题,我们可以预期实际的断言将被执行,如果它没有发生,则测试失败。这可以用expect.assertions
,它可以验证在测试期间有一定数量的断言被调用,这是很容易做到的。
it('throws an error when first argument is `null`', () => {
expect.assertions(1);
try {
samePasswordsValidator(null, "bar");
} catch (error) {
expect(error.message).toBe("no password given");
}
});
现在,当没有异常被抛出时,测试失败。
Error: expect.assertions(1)
Expected one assertion to be called but received zero assertion calls.
toThrow
断言(最佳)
为了使代码更有表现力,可以使用一个内置的toThrow
匹配器。
it('throws an error when first argument is `null`', () => {
expect(() => samePasswordsValidator(null, "bar")).toThrow("no password given");
});
同样,当没有抛出异常时,Jest会用一个失败的测试清楚地告诉我们这一点。
Error: expect(received).toThrow(expected)
Expected substring: "no password given"
Received function did not throw
请注意,toThrow
匹配器不仅可以用来检查错误信息,还可以检查错误的确切类型。
it('throws an error when first argument is `null`', () => {
expect(() => samePasswordsValidator(null, "bar")).toThrow(Error);
expect(() => samePasswordsValidator(null, "bar")).toThrow(new Error("no password given"));
});
参见
转载自:https://juejin.cn/post/7125708300515016735