ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 11/25 TIL | MSW? 그게 뭔데.. 그거 어떻게 하는 건데..
    📝 기록/매일의 기록 2022. 11. 25. 14:58

    이번 주 풀스택 강의에서는 정말 풀스택 프로젝트를 위한 모든 개념들이 다루어진다. 오늘 정리할 개념은 그중 MSW! 우선 그러기 전에 프론트엔드 작업에서 API 모킹을 하는 법에 대해 알아볼 필요가 있다. 이번 강의 기준으로 아샬님은 총 3번 ApiService를 모킹하신다. 그렇다면 차례대로 정리해보자.

    📂 src > services > ApiService.js

    import axios from 'axios';
    
    const baseUrl = 'http://localhost:8000';
    
    export default class ApiService {
      async postSession({ accountNumber, password }) {
        const url = `${baseUrl}/session`;
    
        const { data } = await axios.post(url, { accountNumber, password });
    
        return {
          accessToken: data.accessToken,
          name: data.name,
          amount: data.amount,
        };
      }
    }
    
    export const apiService = new ApiService();

    우선 ApiService는 위와 같이 session을 post하면 accessToken, name과 amount를 반환하는 api 메서드인 postSession 메서드가 존재한다. 이에 대한 테스트 코드를 작성하기 위해 postSession 메서드를 모킹해야 한다.

    1. jest.mock()으로 모킹하기

    📂 src > stores > BankStore.test.js

    jest.mock('../services/ApiService', () => ({
      apiService: {
        async postSession({ accountNumber, password }) {
          if (accountNumber === '1234' && password === 'password') {
            return {
              accessToken: 'ACCESS.TOKEN',
              name: 'Tester',
              amount: 100_000,
            };
          }
    
          throw new Error('Login Failed!');
        },
      },
    }));

    모킹해야 하는 BankStore.test.js의 상단에 jest.mock()으로 ApiService 모듈을 바로 모킹한다.

    2. jest.mock()으로 모킹하기. 근데 이제 __mocks__ 폴더를 곁들인..

    📂 src > services > __mocks__ > ApiService.js

    export default class ApiService {
      async postSession({ accountNumber, password }) {
        if (accountNumber === '1234' && password === 'password') {
          return {
            accessToken: 'ACCESS.TOKEN',
            name: 'Tester',
            amount: 100_000,
          };
        }
    
        throw new Error('Login Failed!');
      }
    }
    
    export const apiService = new ApiService();

    📂 src > stores > BankStore.test.js

    jest.mock('../services/ApiService');

    두 번째로는 __mocks__ 파일에 ApiService.js를 만들고 1번에 jest.mock() 안에 있던 내용을 옮기면, BankStore.test.js는 훨씬 간략해진다!

    3. MSW 사용하여 모킹하기

    📂 src > testServer.js

    import { rest } from 'msw';
    import { setupServer } from 'msw/node';
    
    import config from './config';
    
    const baseUrl = config.apiBaseUrl;
    
    const server = setupServer(
      rest.post(`${baseUrl}/session`, async (req, res, ctx) => {
        const { accountNumber, password } = await req.json();
    
        if (accountNumber === '1234' && password === 'password') {
          return res(
            ctx.json({
              accessToken: 'ACCESS.TOKEN',
              name: 'Tester',
              amount: 100_000,
            }),
          );
        }
    
        return res(ctx.status(400));
      }),
    );
    
    export default server;

    📂 src > stores > BankStore.test.js

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

    세 번째로 MSW 라이브러리를 사용해서 모킹한다.


    세 번째 방식인 MSW는 Mock Service Worker로 서비스 워커(Service Worker)를 이용하여 API를 모킹하는 라이브러리를 말한다. MSW의 가장 큰 강점은 모킹이 네트워크 단에서 일어나기 때문에 프론트엔드 코드를 실제 백엔드 API와 네트워크 통신하는 것과 크게 다르지 않게 작성할 수 있다는 것이다. 즉, 실제 API로 대체하는 것이 쉬워 나중에 실제 API를 적용할 때 프론트엔드 코드를 수정할 일이 적어진다는 것을 의미한다.

    사실 당장에 작업하고 있는 코드들은 1~2번 방식으로 충분히 커버할 수 있지만, 만약 모킹해야 할 API가 많아진다든지 실제 실무에서는 아무래도 MSW를 사용해야 생산성이 높겠다는 생각이 들었다. 그래서 앞으로는 MSW를 사용해서 API 모킹을 하는 데에 더 익숙해져야겠다는 생각도 동시에 들었다.

    뿐만 아니라 이번 강의에서는 프론트와 백을 동시에 진행하면서 작업을 했기 때문에 단순히 API 모킹하는 효율적인 방법이라는 느낌 뿐이었는데, 오늘 TIL로 정리해보면서 찾아보는데, 만약 프론트에서 이렇게 가짜 API를 만들어 개발할 수 있다면, 굳이 백엔드에서 API를 완성하기까지 기다리지 않아도 프론트 쪽 개발을 할 수 있겠구나 하는 생각도 들었다👍