如果您正在等待任何异步函数调用,是否需要使用expect.assertions()?

时间:2018-06-12 11:39:15

标签: jestjs

在重构我们的Jest测试套件时,我发现了很多这样的事情:

it('calls the API and throws an error', async () => {
  expect.assertions(2);
  try {
    await login('email', 'password');
  } catch (error) {
    expect(error.name).toEqual('Unauthorized');
    expect(error.status).toEqual(401);
  }
});

我认为expect.assertions(2)行在这里是多余的,可以安全删除,因为我们已经awaitlogin()进行了异步调用。

我是否正确,或者我误解了expect.assertions的工作原理?

5 个答案:

答案 0 :(得分:7)

expect.assertions在测试异步代码的错误情况时很重要,并且不是多余的。

如果从示例中删除expect.assertions,您将无法确定login确实引发了错误。

it('calls the API and throws an error', async () => {
  try {
    await login('email', 'password');
  } catch (error) {
    expect(error.name).toEqual('Unauthorized');
    expect(error.status).toEqual(401);
  }
});

假设某人根据其他逻辑更改了login的行为以引发错误,或者某人影响了此测试的模拟,而该模拟不再导致login抛出。 catch块中的断言不会运行,但测试仍会通过。

在测试开始时使用expect.assertions可确保如果catch内的断言不运行,则会导致失败。

答案 1 :(得分:2)

这是来自Jest文档:

  

Expect.assertions(number)验证一定数量的断言   在测试期间调用。这在测试时通常很有用   异步代码,以确保回调中的断言   实际上被召唤了。

换句话说,expect.assertions 确保在运行测试时发出n个断言

特别是在编写新测试时,使用它很有用,因此可以轻松检查测试期间是否进行了正确的断言。异步测试很容易通过,因为在测试之前没有做出预期的断言,认为它已经准备好了。

如果您确信您的测试按预期工作,那么它们肯定会被删除。

答案 2 :(得分:1)

我必须承认,除了错误测试之外,我发现很难看到 expect.assertions 的真正用途。上面的代码段可以在相同的保证下更改为以下代码,但我认为它读起来更自然,不需要我计算调用 expect 的次数。如果测试很复杂,这尤其容易出错:

it('calls the API and throws an error', async () => {
  try {
    await login('email', 'password');
    fail('must throw')
  } catch (error) {
    expect(error.name).toEqual('Unauthorized');
    expect(error.status).toEqual(401);
  }
});

答案 3 :(得分:0)

要确保对异步/等待测试的catch块中的断言进行了充分的测试,必须按照代码片段中的说明声明expect.assertions(n)。对于没有catch块的异步/等待测试,不需要这样的声明。

这似乎很不直观,但这只是事实。也许,由于某些原因,在JavaScript运行时的深处,测试环境可以检测到何时成功解决了一个等待的诺言,但无法检测到未能解决的等待的诺言。测试环境的创建者可能会逐字知道为什么会这样。

答案 4 :(得分:0)

我认为我们在这里遗漏了显而易见的东西。

expect.assertions(3) 只是说 ...

我希望在测试超时之前调用 3 个期望语句。例如

expect(actual1).toEqual(expected1);
expect(actual2).toEqual(expected2);
expect(actual3).toEqual(expected3);

这种超时业务是使用expect.assertions的原因。在纯同步测试中使用它是愚蠢的。至少可以在规范文件中的订阅块(或其他异步块)中找到一个 expect 语句。