일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- storybook
- backend
- JPA
- RTK
- react-hook-form
- ReactHooks
- golang
- JavaSpring
- test
- springboot
- hook
- 오블완
- Redux
- Chakra
- javascript
- java
- 티스토리챌린지
- Gin
- React
- satisfiles
- frontend
- typescript
- go
- designpatterns
- component
- 웹애플리케이션서버
- Spring
- tanstackquery
- css
- Today
- Total
bkdragon's log
[TEST] MSW와 통합 테스트 본문
MSW는 서비스 워커(Service Worker)를 사용하여 네트워크 호출을 가로채는 API 모킹(mocking) 라이브러리이다. 백엔드 api가 만들어지기 전에 mock 데이터를 이용해 통합 테스트를 해 볼 수 있다. 브라우저 환경 노드환경 모두 사용할 수 있다.
서비스 워커
서비스 워커는 웹 응용 프로그램, 브라우저, 그리고 (사용 가능한 경우) 네트워크 사이의 프록시 서버 역할한다. 서비스 워커의 개발 의도는 여러가지가 있지만, 그 중에서도 효과적인 오프라인 경험을 생성하고, 네트워크 요청을 가로채서 네트워크 사용 가능 여부에 따라 적절한 행동을 취하고, 서버의 자산을 업데이트할 수 있다. 또한 푸시 알림과 백그라운드 동기화 API로의 접근도 제공한다.
설치 및 세팅
설치
npm install msw --save-dev
# or
yarn add msw --dev
노드환경과 브라우저환경 모두에서 사용할 수 있는 세팅을 정리하려고 한다.
src/mocks/brower.ts
생성
import { setupWorker } from 'msw'
import { handlers } from './handler'
export const worker = setupWorker(...handlers)
src/mocks/server.ts
생성
import { setupServer } from 'msw/node'
import { handlers } from './handler'
export const server = setupServer(...handlers)
src/mocks/handler.ts
생성
import { rest } from 'msw'
export const handlers = [
return rest.get(url, (req, res, ctx) => {
return res(ctx.status(200), ctx.json(data))
})
]
핸들러는 url, http 메서드 별로 나눌 수 있다. 직접 작성한 예시로 tasks를 받아오는 핸들러이다. tasks의 내용은 임으로 정하면 된다.
const getTasks = () => {
return rest.get('https://localhost:3000/tasks', (_, res, ctx) => {
return res(ctx.status(200), ctx.json(tasks))
})
}
setUpTest.ts
파일에 server 전처리 추가
import "@testing-library/jest-dom"; // 기존에 jest 세팅할 때 이미 있는 import
import { server } from "./mocks/server"; // 위에서 생성한 server (node 환경)
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
브라우저 환경의 경우 개발 모드에만 mock 데이터를 받게 처리해줘야 한다. index.ts
파일에 아래 내용을 추가
if (process.env.NODE_ENV === 'development') {
const { worker } = require('./mocks/browser')
worker.start()
}
이렇게 하면 개발 모드 브라우저와 노드 환경에서 api 통신을 탈취해 미리 handler에서 정해둔 mock 데이터를 반환한다 이를 통해 통합 테스트를 진행할 수 있는데 일부러 에러를 발생시켜서 에러 관련 테스트도 진행할 수 있다.
테스트 코드
describe('todoContainer', () => {
const renderTodoContainer = () =>
render(
<TodoContainer />
)
context('데이터를 불러오는 api 호출을 할 때', () => {
context('에러가 발생하지 않았다면', () => {
it('데이터가 화면에 렌더링 되어야 한다..', async () => {
renderTodoContainer()
const task = await screen.findByText('자기')
await waitFor(() => {
expect(task).toBeInTheDocument()
})
})
})
context('에러가 발생했다면', () => {
it('에러를 감지해야한다.', async () => {
server.use(
rest.get('https://localhost:3000/tasks', (_, res, ctx) => {
return res(ctx.status(400), ctx.json({
errorMessage : 'Network error'
}) )
})
)
renderTodoContainer()
const error = await screen.findByTestId('errorMessage')
await waitFor(() => {
expect(error).toBeInTheDocument()
})
})
})
})
})
이제 TodoContainer 컴포넌에서 해당 api를 호출하는 코드를 작성하고 테스트코드와 일치하게 에러처리를 해주면 테스트에 통과할 것이다.
'concept' 카테고리의 다른 글
JavaScript 엔진이 await를 만났을 때 (0) | 2023.07.18 |
---|---|
Flux 패턴 (0) | 2023.07.17 |
[TEST] 프론트의 단위 테스트와 BDD (0) | 2023.07.09 |
[Test] Jest, React-testing-library (0) | 2023.07.07 |
[JavaScript] Call Stack, Callback Queue (0) | 2023.06.24 |