Jestjs 如果';您在等待任何异步函数调用吗?
在重构我们的Jest测试套件时,我发现了很多这样的事情: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
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就不需要了?