如何在 Jest 中测试抛出异常的类型

新手上路,请多包涵

我正在使用一些代码,我需要测试函数抛出的异常类型(是 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 重写我的测试,但找不到如何轻松地做到这一点。甚至可能吗?

原文由 bartsmykla 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.8k
2 个回答

在 Jest 中,您必须将一个函数传递给 expect(function).toThrow(<blank or type of error>)

例子:

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

原文由 PeterDanis 发布,翻译遵循 CC BY-SA 4.0 许可协议

这有点奇怪,但它有效,恕我直言,可读性很好:

 it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
  try {
      throwError();
      // Fail test if above expression doesn't throw anything.
      expect(true).toBe(false);
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});

Catch 块捕获您的异常,然后您可以测试您引发的 Error 。如果预期的 Error 不会被抛出,则需要奇怪的 expect(true).toBe(false); 才能使测试失败。否则,这条线永远无法到达( Error 应该在他们之前提出)。

@Kenny Body 提出了一个更好的解决方案,如果您使用 expect.assertions() 可以提高代码质量:

 it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
  expect.assertions(1);
  try {
      throwError();
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});

请参阅带有更多解释的原始答案: How to test the type of a thrown exception in Jest

编辑 2022:

要使用此方法而不触发 no-conditional-expect 规则(如果您使用的是 eslint-plugin-jest ),此规则的文档建议使用错误包装器:

 class NoErrorThrownError extends Error {}

const getError = async <TError>(call: () => unknown): Promise<TError> => {
  try {
    await call();

    throw new NoErrorThrownError();
  } catch (error: unknown) {
    return error as TError;
  }
};

describe('when the http request fails', () => {
  it('includes the status code in the error', async () => {
    const error = await getError(async () => makeRequest(url));

    // check that the returned error wasn't that no error was thrown
    expect(error).not.toBeInstanceOf(NoErrorThrownError);
    expect(error).toHaveProperty('statusCode', 404);
  });
});

请参阅: no-conditional-expect 文档

原文由 Paweł BB Drozd 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题