7

我有一个运行 2000 毫秒的异步函数,然后它会抛出异常。我正在尝试用 Mocha / chai 准确地测试这种行为,但显然我做错了。

这就是我尝试过的:

第一的:

expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)).to.eventually.throw();

这将测试标记为通过(52 毫秒运行时间),但在 2 秒后抛出异常。所以显然它根本没有等待该功能的承诺。

第二:

expect(async () => {
      await publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000);
    }).to.throw();

测试失败:应该在预定义的超时后拒绝预定的消息:AssertionError:预期 [Function] 在 Context.mocha_1.it (test\integration\rpc-communication.spec.ts:75:16) 处抛出错误

预期的行为是测试通过,因为 2000 毫秒后抛出异常,这是在给定的测试用例超时 4000 毫秒内。

附加信息:

这会奏效。承诺因错误而被拒绝(我也可以将其更改为使用字符串拒绝)。这应该证明 dispatchMessage() 正在按预期工作。测试用例需要 2002 毫秒然后通过。

    try {
      await publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000);
    } catch (err) {
      expect(err).to.be.an('Error');
    }

问题:

如何正确测试异步函数是否引发异常?

4

3 回答 3

8

.to.throw()不应该在async函数上工作,因为它不会抛出错误,它会返回被拒绝的承诺。

这个问题是特定于 chai-as-promised 的。如本期所述,.to.eventually.throw()不会按预期工作。它断言一个Promise使用一个函数解析,该函数在调用时会同步抛出错误。这可能不会发生在dispatchMessage.

这取决于dispatchMessage但可能应该是:

expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000))
.to.be.rejected;
于 2018-04-22T23:16:59.280 回答
3

Chai 支持 async/await 测试功能。要断言拒绝承诺,您可以使用rejectedrejectedWith来自chai-as-promise插件。

因为rejected返回一个 Promise,所以您需要await在 Promise 被拒绝之前完成一个测试用例。

it('should be rejected', async () => {
  await expect(
    publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)
  ).to.be.rejected;
}
于 2018-09-06T10:48:26.043 回答
0

其他答案对我不起作用(也许我没有正确的 Chai 版本?),所以这就是我解决它的方法。

首先,定义这个 util 函数:

const shouldReject = async (promise:Promise<any>, errorClass?:Function|Error, message?:string):Promise<void> => {
  let error = null;
  try {
    await promise;
  }
  catch (e) {
    error = e;
  }
  expect(error).to.not.be.null;
  if(errorClass !== undefined)
    error.should.be.an.instanceOf(errorClass);
  if(message !== undefined)
    error.message.should.equal(message);
};

在您的示例中,您可以像这样使用它:

it('should be rejected', async () => {
  await shouldReject(
    publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)
  );
}
于 2022-02-16T22:11:35.233 回答