Necessary to use expect.assertions() if you're awaiting any async function calls?

*爱你&永不变心* 提交于 2020-11-26 06:22:32

问题


I've found a lot of this sort of thing when refactoring our Jest test suites:

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);
  }
});

I believe the expect.assertions(2) line is redundant here, and can safely be removed, because we already await the async call to login().

Am I correct, or have I misunderstood how expect.assertions works?


回答1:


expect.assertions is important when testing the error scenarios of asynchronous code, and is not redundant.

If you remove expect.assertions from your example you can't be confident that login did in fact throw the error.

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);
  }
});

Let's say someone changes the behavior of login to throw an error based on some other logic, or someone has affected the mock for this test which no longer causes login to throw. The assertions in the catch block won't run but the test will still pass.

Using expect.assertions at the start of the test ensures that if the assertions inside the catch don't run, we get a failure.




回答2:


This is from Jest documentation:

Expect.assertions(number) verifies that a certain number of assertions are called during a test. This is often useful when testing asynchronous code, in order to make sure that assertions in a callback actually got called.

So to put in other words, expect.assertions makes sure that the n number of assertions are made by the end of the test.

It's good to use it especially when writing a new tests, so one can easily check that correct assertions are made during the test. Async tests often pass because the intended assertions were not made before the test-runner (Jest,Mocha etc.) thought the test was finished.




回答3:


To ensure that the assertions in the catch block of an async/await test are adequately tested, expect.assertions(n) must be declared as shown in your code snippet. Such declaration is unnecessary for async/await tests without the catch block.

It seems quite unintuitive but it is simply the way it is. Perhaps, for certain reasons well deep within the javascript runtime, the test environment can detect when an await'ed' promise successfully resolved but cannot detect same for await'ed' promises that failed to resolve. The creators of the test environment would likely know verbatim why such is the case.



来源:https://stackoverflow.com/questions/50816254/necessary-to-use-expect-assertions-if-youre-awaiting-any-async-function-calls

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!