尽管测试运行良好,但笑话测试执行仍显示UnhandledPromiseRejectionWarning

时间:2020-10-12 18:48:34

标签: javascript unit-testing testing jestjs

我将尝试用最少的复制代码来描述问题。

所以我有一个具有这种依赖性的函数:

import "./styles.css";

function thatRecivesInjectedDependency(aDependency) {
  aDependency
    .doSomethingAsync()
    .then((result) => {
      console.log("it happened");
    })
    .catch((error) => {
      throw error;
    });
}

export default thatRecivesInjectedDependency;

我想用像这样的双重测试来测试它:

import sut from ".";

test("should throw an error if the the assets load went wrong", async () => {
  const fakeDependency = {
    doSomethingAsync: jest
      .fn()
      .mockImplementation(() => Promise.reject(new Error("ERROR!")))
  };

  sut(fakeDependency);

  await expect(fakeDependency.doSomethingAsync).rejects.toThrowError(
    new Error("ERROR!")
  );
});

由于某种原因,这是我发现可以进行测试的唯一方法,它不会给我带来假阳性结果,您可以通过更改mockImplementation或{{1}中的错误文本来进行检查},它将失败,但仍然显示:

toThrowError

任何线索,它正在发生什么,如何解决?出什么事了吗?

1 个答案:

答案 0 :(得分:0)

这是无人操作:

.catch((error) => {
  throw error;
});

catch可以被开发人员视为已处理的错误,但此错误只是将其抛出。如果意图是允许调用者处理错误,则可以将其省略。如果要抑制错误,可以将其更改为catch(() => {}),但这可能会导致其他错误,因为调用者无法确定是否有错误,但这很重要。

thatRecivesInjectedDependency不返回承诺,并且存在松散的承诺链。呼叫者无法链接它并等待thatRecivesInjectedDependency完成。 catch不能真正处理错误,因此无法在调用方中处理错误。

应该是:

  return aDependency
    .doSomethingAsync()
    .then((result) => {
      console.log("it happened");
    });

测试不会链接结果,这将导致未处理的拒绝。相反,它会进行自我测试,因为它断言了模拟函数拒绝了。这是众所周知的,因为这正是上面几行写的。

可以通过断言console.log来增加覆盖范围。

应该是:

  jest.spyOn(console, 'log');
  await expect(sut(fakeDependency)).rejects.toThrowError("ERROR!");
  expect(console.log).not.toBeCalled();

请注意,toThrowError(new Error("ERROR!"))过多,因为它只检查错误构造函数或消息,但不能同时检查两者。

相关问题