开玩笑:测试是否将引发异常不起作用

sen*_*rio 2 node.js jestjs

这个琐碎的类只是一个例子...

class SomeClass{
    getTemplateName() {
        throw new Error('foo');
    }
}
Run Code Online (Sandbox Code Playgroud)

...以尝试测试某些代码引发异常

describe('dome class', () => {
    test('contains a method that will throw an exception', () => {
        var sc = new SomeClass();
        expect(sc.getTemplateName()).toThrow(new Error('foo'));
    });
});
Run Code Online (Sandbox Code Playgroud)

但不起作用。我做错了什么?

小智 26

在 Jest 中,当您测试应该抛出错误的情况时,在被测函数的 expect() 包装中,您需要提供一个额外的箭头函数包装才能使其工作。IE

错误(但大多数人的逻辑方法):

expect(functionUnderTesting();).toThrow(ErrorTypeOrErrorMessage);
Run Code Online (Sandbox Code Playgroud)

对:

expect(() => { functionUnderTesting(); }).toThrow(ErrorTypeOrErrorMessage);
Run Code Online (Sandbox Code Playgroud)

这很奇怪,但应该使测试成功运行。

  • 文档指出:“注意:您必须将代码包装在函数中,否则错误将不会被捕获并且断言将失败。”我同意它的用法是意外的 https://jestjs.io/docs/expect#tothrowerror (12认同)
  • 这并不是那么意外,我的意思是它的必要性是有道理的。什么时候。运行“expect(functionUnderTesting()).toThrow(ErrorTypeOrErrorMessage);”,我们必须查看所有内容的运行顺序。首先,执行“functionUnderTesting()”,然后将返回值传递给“expects()”。 ..)`。这里的问题是,在 Jest 知道有关抛出异常的任何事情之前,我们就已经抛出了它。该上下文中的异常将停止执行并失败。当我们将它包装在箭头函数中时,我们实际上还没有执行它,Jest 可以为异常做好准备。 (4认同)

Mig*_*rón 5

开玩笑的文档说

如果要测试引发特定错误,可以为toThrow提供参数。参数可以是错误消息的字符串,错误的类或应与错误匹配的正则表达式。

所以你应该这样编码:

        expect(sc.getTemplateName).toThrow('foo');
Run Code Online (Sandbox Code Playgroud)

要么:

        expect(sc.getTemplateName).toThrow(Error);
Run Code Online (Sandbox Code Playgroud)

更新:更正的expect参数。