문제 발생
웹 서비스를 개발하던 중에, 다음과 같이 특정 API를 호출하고 실패했을 때 window.alert
로 사용자에게 오류 메시지를 보여주는 기능을 구현했습니다. 버튼을 클릭하면 로딩이 보이면서, API 호출이 마무리될 때까지 기다렸다가 성공하면 다음 페이지로 이동하고, 실패하면 오류 메시지를 보이는 형태입니다.
위의 기능과 관련된 컴포넌트에 대한 테스트 코드를 작성하고 있던 중이었습니다.
API를 모킹해서 실패하도록 처리한 후, 오류 메시지를 보이는 것. 즉, window.alert
가 실행되었는 지 검증하는 중이었는데요.
다음과 같은 오류가 발생했습니다.
Jest의 테스트 환경 (testEnviroment)는 jest-environment-jsdom
으로 셋팅되어 있는데요.
JSDOM 환경에는 window.alert
가 구현이 안되어 있는 것입니다.
결국 window.alert
를 모킹해서 테스트를 검증해야 합니다.
Jest에서 제공하는 기능 중, 두 가지를 사용해서 위의 문제를 해결할 수 있었습니다.
jest.fn 사용하기
Jest에서 제공하는 모킹 함수를 사용하는 것입니다.
window.alert
를 모킹 함수로 대체하고, window.alert('오류 메시지')
형태의 함수를 실행하기 때문에, 인자(argument)로 오류 메시지를 잘 받는 지 검증하면 됩니다.
it('API 실패 시, 에러 메시지를 보여준다.', async () => {
// API 호출하는 코드 ... (생략)
// window.alert를 모킹 함수로 대체
window.alert = jest.fn();
// 버튼을 클릭하면 API를 호출합니다.
fireEvent.click(screen.getByText('쪽지 작성완료'));
// 비동기적으로 API를 호출하기 때문에 waitFor를 사용했습니다.
await waitFor(() => {
// 오류 메시지를 인자로 받는 지 검증합니다.
expect(window.alert).toBeCalledWith('쪽지 작성하기를 실패했습니다.');
});
});
jest.spyOn 사용하기
jest.spyOn
은 jest.fn()
과 비슷하게 모킹 함수를 생성해서 리턴하지만, 특정 객체의 메소드를 추적(Track)하는 기능을 제공합니다. 원본 객체를 수정하지 않고, 어떤 행동을 하는 지 감시할 수 있는데요.
앞서 설명했듯이, JSDOM에서는 window.alert
가 구현되어 있지 않기 때문에, 단순하게 jest.spyOn
을 사용하면 window.alert
가 없다는 오류가 발생합니다.
다행히 jest.spyOn
도 추적하는 메소드를 모킹할 수 있는데요.
jest.fn()
과 똑같이 mockImplementation(fn)
을 사용하면 됩니다.
it('API 실패 시, 에러 메시지를 보여준다.', async () => {
// API 호출하는 코드 ... (생략)
// window.alert를 추적, 모킹
const spy = jest.spyOn(window, 'alert').mockImplementation(() => null);
// 버튼을 클릭하면 API를 호출합니다.
fireEvent.click(screen.getByText('쪽지 작성완료'));
// 비동기적으로 API를 호출하기 때문에 waitFor를 사용했습니다.
await waitFor(() => {
// 이번엔 spy 함수가 오류 메시지를 인자로 받는 지 검증합니다.
expect(spy).toBeCalledWith('쪽지 작성하기를 실패했습니다.');
});
});
위의 두 가지 방법 중, 한 가지를 선택해서 테스트 코드를 작성하면 테스트를 성공적으로 통과하게 됩니다.
'개발이슈' 카테고리의 다른 글
[Jest] Web Storage 테스트하기 (LocalStorage, SessionStorage) (0) | 2023.08.05 |
---|---|
[개발이슈] Storybook에서 SVG 이슈 발생 (Element type is invalid ... ) (0) | 2023.07.06 |
[GitLab] The pipeline failed due to the user not being verified 이슈 해결 (0) | 2023.03.09 |
[Next.js] Component selectors can only be used in conjunction 이슈 (0) | 2022.08.07 |
[Next.js] Jest + Cypress 환경에서 Cypress 제공함수의 타이핑 & 자동완성이 안되는 경우 (0) | 2022.04.29 |