인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

정민기님의 프로필 이미지

작성한 질문수

테스트 with Jest: 제로초에게 제대로 배우기

mockImplementation, mockReturnValue

안녕하세요 jest toHaveBeenCalledTimes 관련 질문드립니다.

작성

·

83

0

전체 코드는 다음과 같습니다.

image.pngimage.png

(오류내용)

image.png

 

mock 관련 toHaveBeenCalledTimes 질문드릴려는데요. toHaveBeenCalledTimes가 처음에는 기대값이 1로 맞아서 에러가 안나는데요.

두번째 테스트부터 첫번쨰 테스트에서 호출된 obj.minus 함수가 호출이 읽혀서 그런지 toHaveBeenCalledTimes의 기대값이 2가 됩니다.

세번쨰 테스트도 위에서 호출된게 있어서 그런지 기댓값이 5가 되구요

네번째 테스트도 마찬가지입니다. 원래 toHaveBeenCalledTimes 함수가 다른 테스트케이스에서 사용된 함수도 읽히는지 궁금합니다.

답변 2

0

Rachel님의 프로필 이미지

저도 같은 이슈를 겪었는데 jest.spyOn()으로 만든 mock은 테스트 간에 누적됩니다.

 

obj.minus는 mockFunction.ts에서 공유되는 단일 객체이기 때문에, jest.spyOn(obj, "minus")로 만든 spy/mock이 이전 테스트의 상태를 유지합니다.

 

즉, test A에서 한 번 호출되면, test B에서는 이미 call count = 1로 시작하게 돼요. 그래서 toHaveBeenCalledTimes(2)처럼 누적된 값을 보게 되는 거죠.

 

그래서 코드 상단에 다음과 같이 코드를 작성해 초기화 해주면 에러가 안납니다.

afterEach(() => {
  jest.restoreAllMocks();
});

restoreAllMocks()는 jest.spyOn()으로 만든 스파이들을 원래 함수로 되돌리고 호출 횟수도 초기화합니다.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 정민기님.

Jest를 이용한 테스트 중 toHaveBeenCalledTimes 메서드가 테스트마다 호출 횟수가 누적되는 현상에 대해 질문해주셨네요. 기본적으로 toHaveBeenCalledTimes는 하나의 테스트 스위트를 기준으로 호출 횟수를 확인합니다. 각 테스트 케이스에서 독립적으로 함수 호출을 확인하기 위해 아래와 같은 방법을 사용하실 수 있습니다.

해결 방법

  1. 테스트 사이에서 초기화하기:
    각 테스트가 시작되기 전에 함수를 초기화하여 호출 횟수가 다음 테스트에 영향을 미치지 않도록 해야 합니다. beforeEach 함수를 통해 각 테스트 케이스가 시작되기 전에 원하는 작업을 수행할 수 있습니다.
   let minusSpy;

   beforeEach(() => {
     minusSpy = jest.spyOn(obj, 'minus');
   });

   afterEach(() => {
     minusSpy.mockReset();
     minusSpy.mockRestore();
   });
  1. Mock Reset 및 Restore 사용:
    afterEach를 통해 각 테스트가 끝날 때마다 mockReset()mockRestore()를 호출하여 스파이 및 모킹한 함수를 초기 상태로 돌려놓습니다.

이렇게 설정하면 각 테스트 케이스가 독립적으로 수행되며, 이전 테스트의 함수 호출 기록이 다음 테스트에 영향을 미치지 않게 됩니다.

추가 자료

유사한 문제를 다루고 있는 게시글이 있습니다:

이 자료들은 Jest의 mock 기능과 스파이 기능을 더 깊이 이해하는 데 도움이 될 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.