likes
comments
collection
share

用Jest测试JavaScript中的异常

作者站长头像
站长
· 阅读数 17

代码

让我们考虑一个简单的函数,它检查两个密码是否相等,当第一个密码没有被提供时,它会抛出一个错误。

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"));
});

参见