0Pricing
React Academy · 강의

MSW로 비동기 UI와 API 호출 테스트하기

Mock Service Worker로 HTTP 요청을 모의 처리해 데이터를 가져오는 컴포넌트를 테스트합니다.

MSW로 비동기 UI와 API 호출 테스트하기은(는) CoddyKit의 무료 React Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

Mock Service Worker가 필요한 이유

MSW는 네트워크 수준에서 서비스 워커(브라우저) 또는 http 인터셉터(Node)를 사용해 HTTP 요청을 가로챕니다. 따라서 애플리케이션 코드를 수정하지 않고도 API를 모의 처리할 수 있습니다.

MSW 설치

MSW를 설치하고 Jest/Vitest 테스트를 위한 Node 인터셉터를 설정하십시오.

// npm install msw --save-dev

// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw';

export const handlers = [
  http.get('/api/users', () => {
    return HttpResponse.json([{ id: 1, name: 'Alice' }]);
  }),
];

모의 서버 설정

처리기를 사용해 setupServer 인스턴스를 만들고, 테스트 전에 server.listen()을 호출하십시오. 각 테스트 후에는 server.resetHandlers()를 호출하고, 모든 테스트가 끝난 후에는 server.close()를 호출하십시오.

import { setupServer } from 'msw/node';
import { handlers } from './handlers';

const server = setupServer(...handlers);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

데이터를 가져오는 컴포넌트 테스트

데이터 가져오기를 트리거하는 컴포넌트를 렌더링하십시오. MSW가 요청을 가로채 모의 데이터를 반환합니다. 데이터가 로드된 후 사용자에게 보이는 내용을 검증하십시오.

test('shows user list after fetch', async () => {
  render(<UserList />);
  expect(screen.getByText('Loading...')).toBeInTheDocument();
  expect(await screen.findByText('Alice')).toBeInTheDocument();
});

비동기 사용자 인터페이스를 위한 findBy 조회

findBy 조회는 요소가 나타나면 완료되는 프로미스를 반환합니다. 기본 제한 시간은 최대 1초입니다. 비동기 작업 후 나타나는 콘텐츠에 사용하십시오.

// findByText waits for the element to appear
const username = await screen.findByText('Alice');
expect(username).toBeInTheDocument();

// waitFor wraps assertions that need to wait
await waitFor(() => {
  expect(screen.getByText('3 users')).toBeInTheDocument();
});

테스트별 처리기 재정의

테스트 내부에서 server.use()를 사용하면 해당 테스트에서만 기본 처리기를 재정의하는 일회성 처리기를 추가할 수 있습니다.

test('shows error on API failure', async () => {
  server.use(
    http.get('/api/users', () => {
      return HttpResponse.json({ message: 'Server error' }, { status: 500 });
    })
  );

  render(<UserList />);
  expect(await screen.findByText('Failed to load users')).toBeInTheDocument();
});

로딩 상태 테스트

비동기 데이터가 도착하기 전에 렌더링 직후 동기적으로 로딩 표시기를 검증하십시오.

test('shows loading state initially', () => {
  render(<UserList />);
  expect(screen.getByRole('progressbar')).toBeInTheDocument();
  // or
  expect(screen.getByText('Loading...')).toBeInTheDocument();
});

POST 요청 테스트

요청 본문을 검증하고 생성된 리소스를 반환하는 POST 처리기를 정의합니다. 구성 요소가 성공 상태를 반영하는지 검증합니다.

server.use(
  http.post('/api/users', async ({ request }) => {
    const body = await request.json();
    return HttpResponse.json({ id: 2, ...body }, { status: 201 });
  })
);

test('creates a user', async () => {
  const user = userEvent.setup();
  render(<NewUserForm />);
  await user.type(screen.getByLabelText('Name'), 'Bob');
  await user.click(screen.getByRole('button', { name: /create/i }));
  expect(await screen.findByText('User created!')).toBeInTheDocument();
});

현실적인 테스트를 위한 네트워크 지연

delay 유틸리티를 사용하는 MSW 처리기에 인위적인 지연을 추가하여 로딩 사용자 인터페이스를 더 철저하게 테스트합니다.

import { delay } from 'msw';

http.get('/api/users', async () => {
  await delay(200);
  return HttpResponse.json([{ id: 1, name: 'Alice' }]);
})

리액트 쿼리를 사용한 테스트

테스트 간 상태가 유출되지 않도록 각 테스트마다 새로운 QueryClientProvider로 구성 요소를 감쌉니다.

function renderWithQuery(ui: React.ReactElement) {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });
  return render(
    <QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>
  );
}

요청 데이터 검증

처리기 내부에서 요청 감시 함수를 사용하여 애플리케이션이 올바른 요청 본문이나 헤더를 전송했는지 확인합니다.

let capturedBody: unknown;

server.use(
  http.post('/api/login', async ({ request }) => {
    capturedBody = await request.json();
    return HttpResponse.json({ token: 'abc' });
  })
);

test('sends credentials to API', async () => {
  // ... submit form ...
  expect(capturedBody).toEqual({ email: 'a@b.com', password: 'pass' });
});

개발 환경에서 브라우저로 MSW 사용하기

개발 중에는 브라우저에서도 MSW를 사용할 수 있습니다. npx msw init public/을 실행하여 서비스 워커를 설치하고, main.tsx에서 처리기를 가져와 로컬 개발 중에 사용할 모의 API를 설정합니다.

빠른 확인

API 호출이 완료된 후 나타나는 콘텐츠를 검증하려면 어떤 RTL 쿼리 유형을 사용해야 하나요?

요약

MSW는 실제 HTTP 요청을 가로채므로 실제 서버에 접속하지 않고도 현실적인 테스트를 만들 수 있습니다. 테스트마다 처리기를 재정의하려면 server.use()를 사용하고, 비동기 검증에는 findBy를 사용하며, 리액트 쿼리 테스트는 새로운 QueryClientProvider로 감싸십시오.

자주 묻는 질문

“MSW로 비동기 UI와 API 호출 테스트하기” 강의는 무료인가요?

네 — “MSW로 비동기 UI와 API 호출 테스트하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Academy 강의 전체를 잠금 해제할 수 있습니다. React Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“MSW로 비동기 UI와 API 호출 테스트하기”에서 뭘 배우나요?

Mock Service Worker로 HTTP 요청을 모의 처리해 데이터를 가져오는 컴포넌트를 테스트합니다. 브라우저에서 직접 실행하는 실습 코드로 React Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“MSW로 비동기 UI와 API 호출 테스트하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. React Testing Library로 통합 테스트하기
  2. MSW로 비동기 UI와 API 호출 테스트하기
  3. React용 Playwright 시작하기
  4. 양식과 사용자 흐름 엔드 투 엔드 테스트
← React Academy(으)로 돌아가기