-
jest.fn()을 부여한 변수에는 호출 기록이 쌓인다Today I Learned 2022. 10. 12. 23:58
선물하기 페이지 컴포넌트의 테스트를 작성하는 과정에서 모킹한 외부 라이브러리와 직접 만들었던 Store의 함수가 특정 테스트를 수행하는 도중 호출되었는지 검사하는 부분이 있었다.
페이지에서 입력해야 하는 내용을 입력한 뒤, 선물하기 버튼을 누르면 OrderStore를 거쳐 선물한 내역을 백엔드에서 생성하도록 요청하는데, 요청한 결과로 생성된 선물한 내역의 id가 전달되도록 했다. 이때 전달받은 선물한 내역의 id의 존재 유무에 따라 특정 동작을 수행하는지, 하지 않는지를 테스트하고자 했다.
테스트 코드에서 다음과 같이 페이지 컴포넌트에서 사용된 navigate와 fetchUserAmount를 모킹했다.
통과되어야 하는 테스트 코드의 내용은 다음과 같다.
첫 번째 테스트는 통과하는 것을 확인했지만, 두 번째 테스트에서 문제가 발생하는 것을 확인했다.
beforeEach에서 등록 id가 반환되지 않게끔 mockReturnValueOnce로 빈 문자열을 주었는데도 호출이 되었다는 메세지가 출력되는 게 이상했다.
어디서 값을 잘못 부여하고 있나 싶어 작동되는 로직의 이곳저곳에 console.log를 찍어보았고, 의미있는 부분을 한 군데 찾을 수 있었다.
두 번째 console.log가 두 번째 테스트가 수행될 때 출력된 것이다. 빈 문자열이 정상적으로 주어지므로 if문 내부가 실행되지 않을 것임에도 호출되었었다는 기록이 주어지는 것이었다.
두 테스트에서는 같은 jest.fn()이 주어진 하나의 변수를 통해 검증하고 있었으므로 '그렇다면 이전에 호출되었던 기록이 사라지지 않고 기록으로 남아 있는 건가?' 싶은 생각이 들어 자료를 찾아보았다.
게시글의 내용을 살펴보니 jest.fn()으로 모킹한 함수에 .mock.calls.length를 할 수 있는 것 같았다. 혹시나 싶어서 소스코드에 내용을 적용한 뒤 확인해보았다.
정말로 해당 변수에 이전에 호출했었던 기록이 들어 있었다.
일단 문제를 해결하기 위해 해당 변수를 const가 아닌 let으로 변경한 뒤, beforeEach마다 새로운 jest.fn()으로 재할당하는 방식으로 문제를 해결할 수 있었다.
새로운 모킹 함수로 재할당하는 것이 아닌 const 상태이면서도 이전의 기록 같은 것들을 clear해주는 메서드가 있을 것 같기도 하다. 찾아서 기록으로 남겨놓도록 하자.
'Today I Learned' 카테고리의 다른 글
테스트도 결국 좋은 애플리케이션을 만들기 위한 과정인 것 (레벨 테스트 10일차 작업 회고) (0) 2022.10.14 여전히 통제가 안 되는 영역이 있다는 불안감 (레벨 테스트 9일차 작업 회고) (0) 2022.10.13 강행돌파는 결국 언젠가 한 번은 해야 한다 (0) 2022.10.11 무시무시한 소스코드 중복을 줄이는 메서드화의 힘 (레벨 테스트 6일차 작업 회고) (0) 2022.10.10 성능의 최적화가 오히려 코드 가독성에 좋지 않은 영향을 미칠 수 있다 (0) 2022.10.09