본문 바로가기
SPA/React

[React] MSW로 API Mocking 하기 (3) - Node 환경에서 사용하기

by J4J 2023. 10. 11.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 MSW API Mocking 하기 세 번째인 Node 환경에서 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

이전 글

 

[React] MSW로 API Mocking 하기 (1) - MSW란?

[React] MSW로 API Mocking 하기 (2) - Browser 환경에서 사용하기

 

 

반응형

 

 

Node 환경이란?

 

MSW에서는 Browser, Node 총 2개의 환경을 제공해 줍니다.

 

여기서 Node 환경은 Node를 이용하여 실행할 때 발생되는 API 처리를 Mocking 해주는 것을 의미합니다.

 

 

 

Node 환경으로 간단하게 생각해 볼 수 있는 것은 테스트 도구인 Jest를 언급할 수 있습니다.

 

Jest를 이용하여 테스트를 실행시킬 때 발생되는 API들을 MSW에서 가로채 실제 API 서버가 구동되지 않은 상황이거나, 오프라인 상황에서도 우리가 원하는 결괏값을 전달받아 테스트를 진행시킬 수 있습니다.

 

그래서 API 호출이 발생되는 컴포넌트를 테스트할 때 더 빠른 속도와, 부가적인 외부 이슈 없이 테스트를 원활하게 동작할 수 있도록 도와줍니다.

 

 

 

이제 Jest를 이용하여 Node 환경 설정 테스트를 진행해보겠습니다.

 

만약 Jest 설정이 안 되어 있으신 분들은 다음 글들을 참고해 주시면 됩니다.

 

 

 

 

 

설정 방법

 

[ 1. 패키지 설치 ]

 

npm install -D msw

 

 

 

[ 2. handler 및 server 설정 ]

 

handler는 특정 API를 호출했을 때 우리가 원하는 결괏값이 전달될 수 있도록 mocking 값을 정의해 줄 수 있습니다.

 

예를 들어 사람들의 이름을 조회하는 API를 호출해야 될 때 다음과 같이 handler 정의를 해주시면 됩니다.

 

// src/mocks/handlers/person-handler.ts
import { rest } from 'msw';

export const personHandlers = [
    // GET method인 /get-names를 호출하면 다음과 같이 response가 되도록 mocking 정의
    rest.get('/get-names', (req, res, ctx) => {
        const names = ['jimi', 'john', 'scott', 'queen']

        return res(
            ctx.status(200),
            ctx.json(names),
        )
    })
]


// src/mocks/handlers/index.ts
import { personHandlers } from "./person-handler";

// 여러 handler를 한 곳에 묶어서 return
export const handlers = [
    ...personHandlers
]

 

 

 

각 상황에 맞는 값들로 handler 정의를 했다면 handler를 활용하여 server 설정을 다음과 같이 해주시면 됩니다.

 

// src/mocks/server.ts
import { setupServer } from 'msw/node';
import { handlers } from "./handlers";

export const server = setupServer(...handlers);

 

 

 

[ 3. jest.setup에 msw 설정 추가 ]

 

jest.setup 파일에 msw 설정을 다음과 같이 해주시면 됩니다.

 

jest.setup 파일이 없으신 분들은 아마도 setupTests 라는 이름의 형태로 설정 파일이 생성되어 있으실 겁니다.

 

import { server } from './mocks/server';

// 테스트를 시작하기 전 처리 서버 설정
beforeAll(() => server.listen())

// 테스트가 끝날 때 마다 handler reset 처리 (다른 테스트에 영향을 주지 않기 위해)
afterEach(() => server.resetHandlers())

// 테스트가 모두 종료되면 서버 종료
afterAll(() => server.close())

 

 

 

 

테스트

 

위에서 설정한 API를 호출하여 테스트를 하는 페이지와 테스트 코드를 다음과 같이 작성해 보겠습니다.

 

// src/App.tsx
import axios from "axios";
import { useEffect, useState } from "react";

export default function App() {
  const [personNames, setPersonNames] = useState<string[]>([]);

  async function apiGetNames() {
    const res = await axios.get('/get-names');
    if(res.data) {
      setPersonNames(res.data);
    }
  }

  useEffect(() => {
    apiGetNames();
  }, [])

  return (
    <div>
      <div>
        <h2>사람들의 이름을 호출해보겠습니다 !</h2>
      </div>

      <div>
        {personNames.map((personName, index) => (
          <p key={personName} data-testid='person-name-text'>{index+1}번째 이름은 {personName}입니다.</p>
        ))}
      </div>
    </div>
  )
}


// src/App.test.tsx
import { render, screen } from '@testing-library/react';
import App from './App';

describe('app test', () => {
    test('/get-names api msw mocking 처리 확인 테스트', async () => {
        render(<App />);

        const personNameTexts = await screen.findAllByTestId('person-name-text');
        expect(personNameTexts.length).toEqual(4);
    })
})

 

 

 

 mocking 된 API는 총 4개의 이름을 반환하게 되고, 반환되어 만들어진 element의 개수가 4개인지 테스트를 위와 같이 해볼 수 있습니다.

 

코드를 작성하고 실행해 보면 다음과 같이 올바르게 테스트가 통과되는 것을 볼 수 있습니다.

 

jest msw 테스트 결과

 

 

 

 

상황 별 다른 Mocking 처리 (Override)

 

이전 글인 Browser 설정에서도 관련된 내용을 작성한 적이 있습니다.

 

Node 환경에서도 상황은 동일합니다.

 

위와 같이 설정하면 전역적으로 적용되기 때문에 Jest 기준으로 각 테스트 코드들을 작성할 때마다 서로 다른 결과를 확인하고 싶을 수 있습니다.

 

이런 상황들이 필요한 경우 mocking 정의를 override 하여 서로 다른 테스트 결과를 다음과 같이 만들어 주시면 됩니다.

 

 

 

[ 1. 실행되는 테스트에 override handler 정의 ]

 

import { render, screen } from '@testing-library/react';
import { rest } from 'msw';
import App from './App';
import { server } from './mocks/server';

describe('app test', () => {

    ...
    
    test('/get-names api msw mocking 처리 확인 테스트 (override)', async () => {
        server.use(
            // GET method인 /get-names를 해당 페이지에서만 따로 활용
            rest.get('/get-names', (req, res, ctx) => {
              const names = ['override']
      
              return res(
                  ctx.status(200),
                  ctx.json(names),
              )
            })
          )

        render(<App />);

        const personNameTexts = await screen.findAllByTestId('person-name-text');
        expect(personNameTexts.length).toEqual(1);
    })
})

 

 

 

[ 2. 테스트 ]

 

위와 같이 새로운 테스트를 추가해 주고 모든 테스트를 한 번에 실행하게 되면 올바르게 적용되는 것을 확인할 수 있습니다.

 

jest msw override 테스트 결과

 

 

 

 

 

 

 

 

이상으로 MSW API Mocking 하기 세 번째인 Node 환경에서 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글