티스토리 뷰
velog 블로그에서 tistory로 이전한 데이터 입니다. 2020-10-26
들어가기
Jest는 javaScript 테스트 프레임워크다. 가볍고 쉬우며 뛰어난 mock function을 지원해서 많이 사용하는 것 같다.
더군다나 facebook이 만들었으니 react, node.js를 사용하는 개발자들에겐 거의 빠지지않을 툴일 것이다.
오늘 test case를 작성하고 검사하는데 axios에서 mocking이 적용이 잘 안되서 적어두면 나중에라도 도움이 될 것 같아서 적어본다.
사용기
보통은 공식문서에서 참고해 개발하면 쉽게 따라할 수 있지만 생각보다 잘 안되는게 axios를 mocking할 때, 흔히 하는 실수들이다.
크게 보면 두가지 경우라고 볼 수 있다.
- axios를 import해서 사용할 때,
- axios.create를 이용해서 인스턴스를 사용할 때,
라이브러리는 axios-mock-adapter를 추가로 많이 사용할 것이다. 하지만 생각보다 재대로 적용되지 않은 경우가 있었다.
상황
나의 목적은 500, 200, 404에러를 고의로 발생시켜 그에 따른 Error를 핸들링할 수 있는 기능 을 만드는 일이였고
상황은 1번에 처음에 axios-mock-adapter를 사용했다.
axios-mock-adapter를 사용하면 쉽게 axiosMock.onGet( {:주소} ).reply(200) 등으로 쉽게 테스트가 가능한데 계속 404 에러가 나왔다.
당연히 주소 부분에 서버가 켜져있지 않았기 때문에 404에러가 당연한 결과지만 테스트에서 200, 500을 만들고 싶었기 때문에 mocking이 안됐음을 알 수 있다.
고민하기
우리는 자체 axios default instance를 사용하고 있었기 때문에 왜 mock adapter가 필요한지 고민을 했다. jest 도큐먼트를 읽어보면 axios에 대해 mock 함수를 다루는 방법이 나와있었다.
// users.test.js
import axios from 'axios';
import Users from './users';
jest.mock('axios');
test('should fetch users', () => {
const users = [{name: 'Bob'}];
const resp = {data: users};
axios.get.mockResolvedValue(resp);
// or you could use the following depending on your use case:
// axios.get.mockImplementation(() => Promise.resolve(resp))
return Users.all().then(data => expect(data).toEqual(users));
});
// https://jestjs.io/docs/en/mock-functions 에서 확인이 가능하다.
이때, jest.mock은 내부 코드를 보면 일부지만 Instance에 대한 새로운 mock을 만들어내려고 한다.
그러면 jest.mock('axios')는 axios를 copy해 새로운 instance로 변경해 테스트가 가능하다는 점이다.
반면에 axios-mock-adapter는?
2번 상황에 맞는 코드를 작성할 때, adapter의 사용이 맞는 것 같다. 여기
내부 코드를 자세히 살펴보진 못했지만 사람들이 404에러가 발생한 경우에 대해서 많이들 글을 남긴게 있다.
뭐 누구는 browser에서 사용하는데 react 컴포넌트 검사에서 storybook과 raceCondition 문제가 있어서 할 수 없다는 의견도 많고 다른 의견들도 많지만 생략한다.
axios.create를 통해 새로운 인스턴스를 얻어서 mock-adapter에 넣고 쓰면 알맞을 것 같다.
default에서는 axios-mock-adapter를 사용하지 않을 예정이다.
해결 코드 예시
// sudo code
jest.mock('axios');
test('RESPONSE 200 테스트',async ()=>{
// 1. 에러나고 난 뒤 실행될 함수를 mock function 만듬
func = jest.fn().mockResolvedValue([]);
// 2. axios.post 에 대해 200
axios.post.mockImplementation(()=>
Promise.resolve( { response: { status: 200 } } )
);
// 1번 경우의 함수가 불리지 않았는지 체크
expect(func).not.toHaveBeenCalled();
});
test('RESPONSE 500 테스트',async ()=>{
// 1. 에러나고 난 뒤 실행될 함수를 mock function 만듬
func = jest.fn().mockResolvedValue([]);
// 2. axios.post 에 대해 500 에러를 발생
axios.post.mockImplementation(()=>
Promise.reject( { response: { status: 500 } } )
);
// 1번 경우에 해당하는 함수가 불렸는지 체크
expect(func).toHaveBeenCalled();
});
참고
axios-mock-adapter
https://github.com/ctimmerm/axios-mock-adapter/issues/193
https://jestjs.io/docs/en/mock-functions#mocking-modules
'CS > Server' 카테고리의 다른 글
package.json에 있는 command 왜 '--'를 넣을까? (0) | 2023.10.08 |
---|---|
[Content-Type] application/x-www-form-urlencoded 에 대해 이해하기 (0) | 2023.10.08 |
- Total
- Today
- Yesterday
- 너디너리데모데이
- PresignedURL
- UI/UX
- JRE
- PUT vs POST
- 디자인시스템
- 블로킹/논블로킹
- 점진적개선
- 필수단어
- SSAFY 특화프로젝트 회고
- AntPattern
- S3
- 개발프로세스
- 개발기록
- Content-Type
- 클린코드
- charset
- SSAFY 퇴소
- 자바기초
- nodejs
- HTTP
- 2022년 회고
- 트랜잭션
- 콘웨이법칙
- LTS 개선
- nodejs 버전 관리
- 소프트웨어개발프로세스
- application/x-www-form-urlencoded
- 디미터법칙
- 동기/비동기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |