[Jest] Jest를 사용한 비동기 코드 검사

mokyoungg·2021년 4월 28일
1

아래의 내용은 CRA 환경에서 사용하였습니다.

자바스크립트에서는 코드가 비동기적으로 실행되는 것이 흔하다.
Jest는 테스트 중인 코드가 언제 완료가 되었는지 알아야 비동기 코드를 검사할 수 있다.

callbacks

가장 일반적인 비동기 패턴은 콜백이다.

아래의 코드는 비동기 패턴을 위해 작성한 코드이며,
API 콜을 통해 데이터를 받아오는 대신 setTimeout()을 사용하여 콜백함수를 호출하였다.

보기에는 의도대로 테스트가 통과한 것처럼 보이지만 이는 의도한대로 동작하지 않은 코드이다.

test 코드에 toBe('123456')으로 검사하여도 이 코드는 테스트에 통과한다.
왜 이런일이 생기는걸까?

By default, Jest tests complete once they reach the end of their execution. That means this test will not work as intended.
The problem is that the test will complete as soon as fetchData completes, before ever calling the callback.

문제는 콜백을 호출하기 전에 fetchData가 완료됨과 동시에 테스트가 완료된다는 것이다.
기본적으로 Jest 테스트는 실행 종료시 완료가 된다. 이 때문에 테스트가 의도한대로 작동하지 않는 것

Jest는 성능을 위해 테스트를 최대한 빨리 호출한다.
그렇기 때문에 콜백함수는 호출되지 못 하고, 콜백함수에서 test를 해야할 expect().toBe() 역시 호출되지 못 한것이다.

done

done을 인수로 사용하여 이런 문제를 해결할 수 있다.
이를 사용하면 Jest는 테스트의 콜백이 호출될 때까지 기다리고 테스트를 완료한다.

즉, done은 Jest에게 테스트할 코드가 비동기 코드라는 것을 알려주며 콜백의 호출까지 마무리가 되었다(done)는 것을 알려주는 것이다.

  • test 코드의 인수로 done 을 사용하면 비동기 코드를 테스트할 수 있다.
  • done을 쓰지 않았을 때와 썼을 때의 검사 내용을 비교해보면 done을 썼을 때가 더 오래 걸린것으로(약 100ms) 알 수 있는데 비동기코드의 setTimeout에서 작성한 0.1초 이후에 동작하라는 코드가 정상적으로 작동했다는 것을 알 수있다.
  • 만약, try 부분에 done을 호출하지 않으면 시간 초과 오류로 테스트가 실패하게 된다.

이제 정상적으로 테스트가 작동하기 때문에 toBe('1234,,')에서 테스트를 통과하지 못하게 된다.

Promises

  • callback과는 다르게 string이라는 값을 resolve(제공)하는 promise 객체를 리턴하였다.
  • callback의 첫 테스트와 마찬가지로 테스트 시간에 1ms가 소요되었다.(setTimeout은 500으로 작성)
  • 비동기 코드가 제대로 테스트가 되지 않았으며 then() 메서드가 실행되지 못 하였다.

  • string에 'butter'를 넣어도 테스트에 통과됨.

return

promise로 구현된 비동기 코드를 테스트 하기 위해선 return 을 추가하면 된다.
return을 통해 Jest가 Promise가 resolve가 될 때까지 기다려준다.

async await

async await의 경우에는 테스트 함수의 앞에 async를 추가하고
promise를 리턴하는 함수 앞에 await을 붙여주면 된다.




참고

profile
생경하다.

0개의 댓글