Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jestjs 如果';您在等待任何异步函数调用吗?_Jestjs - Fatal编程技术网

Jestjs 如果';您在等待任何异步函数调用吗?

Jestjs 如果';您在等待任何异步函数调用吗?,jestjs,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).t

在重构我们的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)
行在这里是多余的,可以安全地删除,因为我们已经
等待
login()的异步调用


我是对的,还是误解了expect.assertions的工作原理?

这是来自Jest文档:

断言(number)验证一定数量的断言 在测试期间调用。这在测试时通常很有用 异步代码,以确保回调中的断言 实际上有人打过电话

换句话说,expect.assertions确保在测试结束时生成n个断言


使用它是很好的,尤其是在编写新的测试时,这样就可以很容易地检查测试期间是否做出了正确的断言。异步测试通常会通过,因为在测试运行者(Jest、Mocha等)认为测试完成之前,没有做出预期的断言。

expect。断言在测试异步代码的错误场景时非常重要,并且不是多余的

如果从示例中删除
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中的断言没有运行,我们就会失败。

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


这看起来很不直观,但事实就是这样。也许,由于javascript运行时内部的某些原因,测试环境可以检测何时成功解析了等待的“承诺”,但无法检测未能解析的等待的“承诺”。测试环境的创建者可能会一字不差地知道为什么会出现这种情况。

我认为我们忽略了这里显而易见的问题

断言(3)只是说

我希望在测试超时之前调用3个expect语句。e、 g

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

业务超时是使用expect.assertions的原因。在纯粹的同步测试中使用它是愚蠢的。spec文件中的subscribe块(或其他异步块)中至少会找到一个expect语句。

我必须承认,除了错误测试之外,我发现很难看到
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);
  }
});

事实上,它们确实可以被删除,但是我根本不会这么做,为什么愿意冒将来某个给定的更改不会破坏测试的风险呢?因此,如果测试代码在
登录
之后出现类似
失败的情况,那么在这种情况下,
expect.assertions就不需要了?