我正在使用一些代码,其中我需要测试由函数抛出的异常的类型(它是TypeError, ReferenceError等?)

我目前的测试框架是AVA,我可以测试它作为第二个参数t.throws方法,就像这里:

it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', (t) => {
  const error = t.throws(() => {
    throwError();
  }, TypeError);

  t.is(error.message, 'UNKNOWN ERROR');
});

我开始用Jest重写我的测试,但不知道如何轻松地做到这一点。这可能吗?


当前回答

除了Peter Danis的帖子,我只想强调他的解决方案中涉及“将一个函数[传递]到expect(函数)”的部分。toThrow(空白或错误类型)”。

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

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

expect(functionUnderTesting();).toThrow(ErrorTypeOrErrorMessage);

正确的:

expect(() => { functionUnderTesting(); }).toThrow(ErrorTypeOrErrorMessage);

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

其他回答

检查toThrow方法。

您必须将代码包装在一个额外的回调函数中!

您应该同时检查错误消息及其类型。

例如:

expect(
  () => { // additional function wrap
    yourCodeToTest();
  }
).toThrow(
  new RangeError('duplicate prevArray value: A')
);

由于额外的回调换行,代码不会立即运行,因此jest将能够捕获它。

您应该始终检查错误消息,以确保您正在检查正确的抛出情况,而不会得到代码可能抛出的另一个错误。

检查错误类型也很好,因此客户端代码可以依赖它。

如果你正在使用Promises:

await expect(Promise.reject(new HttpException('Error message', 402)))
  .rejects.toThrowError(HttpException);

我自己没有尝试过,但我建议使用Jest的toThrow断言。所以我猜你的例子应该是这样的:

it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', (t) => {
  const error = t.throws(() => {
    throwError();
  }, TypeError);

  expect(t).toThrowError('UNKNOWN ERROR');
  //or
  expect(t).toThrowError(TypeError);
});

同样,我还没有测试它,但我认为它应该可以工作。

还有一种更简单的方法对错误消息进行断言。这种方法的美妙之处在于,您不需要重新构造错误对象或获得完整的错误消息。只要您的错误包含错误消息的一部分,我们就可以假设它的类型是正确的。即

 const printOnlyString = (str) => {
   if(typeof str !== "string"){
     throw Error("I can only print strings ${typeof str) given");
   }
   else {
     console.log(str);
   } 
 }

expect(() => printOnlyString(123))。toThrow(/只能打印字符串/)

Jest有一个方法toThrow(error),用于测试函数在被调用时是否抛出。

所以,在你的情况下,你应该这样称呼它:

expect(t).toThrowError(TypeError);

文档。