Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- React
- 웹애플리케이션서버
- 오블완
- Redux
- hook
- storybook
- test
- component
- go
- Gin
- springboot
- react-hook-form
- golang
- ReactHooks
- JPA
- backend
- 티스토리챌린지
- RTK
- satisfiles
- JavaSpring
- Chakra
- javascript
- Spring
- java
- frontend
- css
- designpatterns
- tanstackquery
- typescript
Archives
- Today
- Total
bkdragon's log
Async Custom Hook Testing 본문
ACHT, 있어보이게 영어로 써보았다.
비동기 커스텀 훅 테스트 코드를 작성해보자. api 통신으로 데이터를 받아오기 때문에 MSW를 이용할 것 이다. 사용법 및 세팅법은 이 글에 잘 설명해두었다.
원래는 커스텀 훅을 사용하는 컴포넌트에서 테스트를 했었는데 커스텀 훅 테스트를 분리한 이유가 있다. delete 통신 성공이 204 no-content 였기 때문이다. 아래 코드의 두개의 핸들러를 비교해보자.
export const getTodos = () => {
return rest.get(`${baseUrl}${paths.todos}`, (_, res, ctx) => {
return res(ctx.status(200), ctx.json(sampleTodos));
});
};
const deleteTodos = () => {
return rest.delete(`${baseUrl}${paths.todos}/:id`, (req, res, ctx) => {
const { id } = req.params;
return res(
ctx.status(204),
);
});
};
get 요청은 응답으로 받는 데이터가 있다. 헌데 delete 요청은 204 no-content 성공이지만 돌려받는 데이터가 없다.
// get
setTodos(resopnse.data);
// delete
setTodos((prev) => prev.filter((todo) => todo.id !== id));
MSW는 응답 탈취하여 Mock Data를 건네주는데 delete는 응답 데이터를 따로 받지 않기 때문에 테스트에서는 상태변화가 일어나지 않는다. 이러한 이유로 delete 기능을 테스트하기 위해 훅을 직접 테스트하는 방법을 택했다. 기본적으로 훅은 리액트 컴포넌트 내부에서만 사용할 수 있다. renderHook을 사용하면 따로 컴포넌트를 만들거나 wrapping 하지 않고 훅을 테스트 할 수 있다.
useTodos의 대표 기능은 할 일 목록 조회, 삭제, 업데이트, 추가 등이 있다.
첫번째 테스트를 작성해보자.
context('useTodos를 호출하면', () => {
it('todo에 두개의 할 일이 들어있다.(초기화)', async () => {
const { result } = await act(async () => setUpCustomHook());
expect(result.current.todos).toHaveLength(2);
});
});
- 두개의 할 일이 들어있는 이유는 get 요청을 탈취해서 두개의 할 일을 받아오도록 미리 세팅해뒀기 때문이다.
- result.current에는 해당 훅이 반환하는 요소들의 현재 상태가 들어간다.
- act는 인자의 callback을 실행시킨 후 가상의 dom에 반영하는 역할을 한다. 상태가 변경될 때 감싼다.
- 내부적으로 컴포넌트 마운트 이후 바로 초기 데이터를 받아오기 위한 함수가 실행되기 때문에 act로 감싸주었다.
이제 deleteTodo 테스트를 작성해보자.
context('deleteTodo', () => {
it('특정 할 일이 삭제 된다.', async () => {
const { result } = await act(async () => setUpCustomHook());
await act(async () => {
result.current.deleteTodo(1);
});
expect(result.current.todos).toHaveLength(1);
});
});
- 마찬가지로 deleteTodo 를 실행하는 부분에도 act로 감싸줬다. (상태가 변경될 것이기 때문)
나머지 메서드도 같은 방식으로 테스트 할 수 있다.
'concept' 카테고리의 다른 글
MVVM 패턴 (0) | 2023.08.10 |
---|---|
module css, classnames로 조건부 스타일링 (0) | 2023.08.07 |
[TEST] Redux 테스트 (0) | 2023.07.29 |
CORS 요리 (0) | 2023.07.29 |
Promise 병렬로 처리하기 (1) | 2023.07.29 |