我正在使用一些代码,其中我需要测试由函数抛出的异常的类型(它是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);

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

其他回答

如果你正在使用Promises:

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

我用了一个稍微简洁一点的版本:

expect(() => {
  // Code block that should throw error
}).toThrow(TypeError) // Or .toThrow('expectedErrorMessage')

从我对Jest的接触(尽管有限)中,我发现expect().toThrow()适用于只想测试抛出的特定类型的错误:

expect(() => functionUnderTest()).toThrow(TypeError);

或者抛出一个带有特定消息的错误:

expect(() => functionUnderTest())。toThrow('发生了不好的事情!');

如果你试图同时做这两件事,你会得到一个假阳性。例如,如果你的代码抛出RangeError('坏事发生了!'),这个测试将通过:

expect(() => functionUnderTest()).toThrow(new TypeError('Something bad Happen!'));

bodolsog给出的答案很接近,它建议使用try/catch,但与其期望true为false以确保捕获中的expect断言被命中,不如在测试开始时使用expect.assertions(2),其中2是预期断言的数量。我觉得这更准确地描述了测试的意图。

测试错误类型和消息的完整示例:

describe('functionUnderTest', () => {
    it('should throw a specific type of error.', () => {
        expect.assertions(2);

        try {
            functionUnderTest();
        } catch (error) {
            expect(error).toBeInstanceOf(TypeError);
            expect(error).toHaveProperty('message', 'Something bad happened!');
        }
    });
});

如果functionUnderTest()没有抛出错误,则断言将被命中,但expect.assertions(2)将失败,测试也将失败。

开玩笑地说,你必须将一个函数传递给expect(函数)。toThrow(<空白或错误类型>)。

例子:

test("Test description", () => {
  const t = () => {
    throw new TypeError();
  };
  expect(t).toThrow(TypeError);
});

或者如果你还想检查错误信息:

test("Test description", () => {
  const t = () => {
    throw new TypeError("UNKNOWN ERROR");
  };
  expect(t).toThrow(TypeError);
  expect(t).toThrow("UNKNOWN ERROR");
});

如果需要测试现有函数是否抛出一组参数,则必须将其包装在expect()中的匿名函数中。

例子:

test("Test description", () => {
  expect(() => {http.get(yourUrl, yourCallbackFn)}).toThrow(TypeError);
});

您必须将期望的函数代码包装在另一个箭头函数中,否则错误将不会被捕获,断言将失败。

要测试的函数:

const testThrowingError = () => {
    throw new Error();
  };

测试:

describe("error function should Throw Error", () => {
  expect(() =>testThrowingError()).toThrowError();
});

资源: https://jestjs.io/docs/expect#tothrowerror