在jest测试中,UnhandledPromiseRejectionWarning的含义是什么?

17
想要测试以下模块 index.ts
async function theFunctionFail() {
  return await fail();
}

async function theFunctionSucceed() {
  return await succeed();
}

async function fail() {
  throw new Error();
}

async function succeed() {
  return "a";
}

export { theFunctionFail, theFunctionSucceed };

使用测试index.test.ts

import { theFunctionFail, theFunctionSucceed } from "../index";

it('theFunctionFail', () => {
  expect(theFunctionFail()).rejects;
});

输出中的UnhandledPromiseRejectionWarning是什么意思?

(node:10515) UnhandledPromiseRejectionWarning: Error
(node:10515) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:10515) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
 PASS  src/__tests__/index.test.ts
  ✓ theFunctionFail (6ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.806s
Ran all test suites.

参考?在一个try-catch(err)块中包裹expect(theFunctionFail()).rejects不能避免我认为值得修复的警告。

为什么测试不会失败?/如何让测试失败?如果我的测试发现了严重的缺陷,那它不应该成功。

我正在使用Typescript和Jest 24.7.1与react-scripts

2个回答

20
这个警告指出测试中发生了未被处理的错误。实际问题在于你的测试没有测试任何内容,使用了一个没有匹配器的expect。以下是正确的写法:

这个警告指出测试中发生了未被处理的错误。实际问题在于你的测试没有测试任何内容,使用了一个没有匹配器的expect。以下是正确的写法:

return expect(theFunctionFail()).rejects.toEqual(new Error());

查看Jest文档中的.rejects部分:https://jestjs.io/docs/en/tutorial-async#rejects

注意:也可以使用try/catch,但必须像这样使用await

it('theFunctionFail', async () => {
  expect.assertions(1);
  try {
    await theFunctionFail();
  } catch (err) {
    expect(err).toEqual(new Error());
  }
});

或者返回异步函数并捕获错误(确保返回该函数):

it('theFunctionFail', () => {
  expect.assertions(1);
  return theFunctionFail().catch(err => {
    expect(err).toEqual(new Error());
  });
});

expect.assertions(number) 是确保在测试异步行为时调用所有 expect 的有效方法。

此外,如果您添加一个错误消息,例如 new Error('oh no!'),则可以确信捕获了正确的错误,并且这将使调试变得更加容易一些。


1
有没有更容易找到有问题的测试的方法?我能做一个临时的猴子补丁吗?对于这个项目,我有超过1000个测试,但错误并不与输出中显示的位置相一致。 - jktravis
听起来你的问题可能出在代码上,而不是测试上。我会确保你的代码没有任何没有.catch的promise,或者任何在try/catch之外的await - helloitsjoe
1
好的。我只是不知道如何在代码中找到它,而不必费力地逐个运行每个测试。 - jktravis
你好,想知道你是否找到了识别有问题的测试用例的方法?或者在本地 jest 运行中重现此问题?我们的 jest 只在 CI 管道中退出,本地一切看起来都很正常。 - Dharshni
1
值得明确指出的是,上面答案中的 return 是至关重要的 - 这告诉 jest 在确定测试结果之前等待 promise 解析或拒绝。 - charlieb

4

在控制台不会产生"UnhandledPromiseRejectionWarning"的最干净的解决方案是使用jest的expect.toThrow()函数。

import { theFunctionFail, theFunctionSucceed } from "../index";

it('theFunctionFail', () => {
  expect(theFunctionFail()).rejects.toThrow();
});

再次尝试匹配特定错误。例如,如果:

async function fail() {
  throw new Error('Something failed');
}

然后,你需要进行以下测试:
it('theFunctionFail', () => {
  expect(theFunctionFail()).rejects.toThrow(Error('Something failed'));
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接