비동기 테스트가 필요한 이유
실제 프로젝트에서는 API 요청, 타이머, Promise처럼 바로 결과가 나오지 않는 코드를 자주 다룹니다.
이런 함수는 테스트에서도 결과가 나올 때까지 기다려야 합니다.
Jest에서는 async와 await를 사용해 비동기 코드를 자연스럽게 테스트할 수 있습니다.
테스트할 함수 만들기
아래 함수는 3초 뒤 "Mike"를 반환합니다.
1
2
3
4
5
6
7
8
9
10
// fn.js
const fetchName = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Mike");
}, 3000);
});
};
export default fetchName;
Promise를 반환하는 비동기 함수입니다.
async/await로 테스트하기
1
2
3
4
5
6
7
8
// fn.test.js
import fetchName from "./fn";
test("fetchName은 Mike를 반환합니다", async () => {
const result = await fetchName();
expect(result).toBe("Mike");
});
테스트 함수 앞에 async를 붙이고, 비동기 함수 앞에 await를 붙였습니다.
Jest는 Promise가 끝날 때까지 기다린 뒤 matcher를 실행합니다.
resolves matcher 사용하기
Promise가 특정 값으로 resolve되는지 확인할 때는 resolves를 사용할 수도 있습니다.
1
2
3
test("fetchName은 Mike를 반환합니다", async () => {
await expect(fetchName()).resolves.toBe("Mike");
});
이 방식은 Promise의 결과값만 바로 검증할 때 간결합니다.
rejected 테스트하기
Promise가 reject되는 상황도 테스트할 수 있습니다.
1
2
3
4
5
6
7
const fetchError = () => {
return Promise.reject(new Error("fail"));
};
test("에러를 반환합니다", async () => {
await expect(fetchError()).rejects.toThrow("fail");
});
실패해야 하는 요청이나 에러 처리 로직을 검증할 때 유용합니다.
타이머가 길면 테스트도 느려져요
위 예시처럼 setTimeout이 3초라면 테스트도 실제로 3초를 기다립니다.
간단한 예제라면 괜찮지만, 테스트가 많아지면 전체 실행 시간이 길어질 수 있습니다.
타이머 로직을 많이 테스트해야 한다면 Jest의 fake timers를 사용하는 방법도 고려할 수 있습니다.
마무리
Jest에서 비동기 코드를 테스트할 때는 테스트 함수에 async를 붙이고, Promise 결과를 await로 기다리면 됩니다.
성공 케이스는 resolves, 실패 케이스는 rejects matcher를 사용하면 더 간결하게 표현할 수 있습니다.
비동기 함수는 결과가 나올 때까지 기다리는 것이 핵심입니다.