study/JavaScript๐ŸŒŸ

[FE] MSW(Mock Service Worker)๋กœ ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ ์‹œ๊ฐ„ ๋‹จ์ถ•ํ•˜๊ธฐ!

cowboysj 2024. 1. 21. 17:43

 

๊ฐœ์š”

์ถœ์ฒ˜ : https://tech.kakao.com/2021/09/29/mocking-fe/

 

ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด, ํ•ญ์ƒ ํ”„๋ก ํŠธ๋งŒ ํ”Œ์  ์ œ์ผ ๋งˆ์ง€๋ง‰ ์ˆœ๊ฐ„๊นŒ์ง€ ๊ฐœ๋ฐœ์„ ํ•˜๊ณ  ์žˆ๋‹ค..

๊ธฐํš, ๋””์ž์ธ์ด ์™„๋ฃŒ๋˜๋ฉด ๋ฐฑ์—”๋“œ๊ฐ€ ๋จผ์ € ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•˜๊ณ , API ๊ฐœ๋ฐœ์ด ๋๋‚œ ๋’ค ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ด ๋“ค์–ด๊ฐ€๋ฉด ์ข‹๊ฒ ์ง€๋งŒ, ํ˜„์‹ค์€ ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ๋™์‹œ์— ์‹œ์ž‘ํ•˜๋Š” ๊ฒŒ ๋Œ€๋ถ€๋ถ„์ด๋‹ค.

 

๊ทธ๋ž˜์„œ ํ”„๋ก ํŠธ์—์„œ๋Š” ๋ฐฑ์—”๋“œ๊ฐ€ ์ค€ API ๋ช…์„ธ์„œ๋ฅผ ๋ณด๊ณ  Mock Data๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋„์šธ ์ค€๋น„๋ฅผ ํ•ด๋†“๋Š”๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•˜๋ฉด, API ๊ฐœ๋ฐœ์ด ๋๋‚œ ๋’ค, ๋˜ ๋งˆ์ง€๋ง‰๊นŒ์ง€ ์™ธ๋กญ๊ฒŒ ๊ฐœ๋ฐœ์„ ํ•ด์•ผํ•œ๋‹ค..ใ… ใ… 

 

์ด๋ฒˆ์— ๋ฐฉํ•™ UMC ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด์„œ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ MSW๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž๋Š” ์–˜๊ธฐ๊ฐ€ ๋‚˜์™”๋‹ค. MSW๋งŒ ์ œ๋Œ€๋กœ ๊ตฌ์ถ•ํ•ด๋†“์œผ๋ฉด, API ์—ฐ๊ฒฐ์„ ๋ฏธ๋ฆฌ ํ•ด๋†“๋Š” ๊ฒƒ๊ณผ ๋˜‘๊ฐ™์•„์„œ ๋‚˜์ค‘์— ๋˜ ๊ฐœ๋ฐœ์„ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด๋ฒˆ ํ”Œ์ ์—์„œ๋Š” ๋ฐฑ์—”๋“œ๋ณด๋‹ค ๊ฐœ๋ฐœ์„ ๋” ๋นจ๋ฆฌ ๋๋‚ด๋ณด์ž~><

 

1.  MSW(Mock Service Worker)๋ž€?

MSW๋ž€ API Mocking ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, Service Worker๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋ฒ„ ์š”์ฒญ์„ ์ค‘๊ฐ„์—์„œ ๊ฐ€๋กœ์ฑ„์„œ mock response๋ฅผ ๋Œ๋ ค์ค€๋‹ค. 

์ถœ์ฒ˜ : https://tech.kakao.com/2021/09/29/mocking-fe/

 

Service Worker๋Š” ๋„คํŠธ์›Œํฌ ์‚ฌ์ด์˜ ํ”„๋ก์‹œ ์„œ๋ฒ„ ์—ญํ• ์„ ํ•ด์ฃผ๋Š”๋ฐ, ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ํ–‰๋™์„ ์ทจํ•˜๊ณ , ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์œ„์™€ ๊ฐ™์ด ๊ธฐ๋ณธ ์„ธํŒ…์„ ํ•ด์ฃผ๊ณ , API ๋ช…์„ธ์„œ๋ฅผ ๋ณด๋ฉด์„œ mockData๋ž‘ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์„ค์ •ํ•ด์ฃผ๊ณ , API ์š”์ฒญ์„ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

MSW๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋–„์˜ ์žฅ์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1. mock data, mock server๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค๊ณ , ๊ตฌ์ถ•ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

2. ์ถ”ํ›„ API ์—ฐ๊ฒฐ ๊ณผ์ •์ด ์ƒ๋žต๋œ๋‹ค.

 

2.  Install

npm install msw --save-dev

 

3. ์‚ฌ์šฉ๋ฒ•

์ €ํฌ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”~ใ…Žใ…Ž

https://github.com/Here-You/FrontEnd

 

GitHub - Here-You/FrontEnd: ์—ฌํ–‰์˜ ์ด์œ  FE

์—ฌํ–‰์˜ ์ด์œ  FE. Contribute to Here-You/FrontEnd development by creating an account on GitHub.

github.com

  1. constants/path.js์—์„œ API_PATH ์ถ”๊ฐ€

const API_PATH = {
  FAVORITE_TRAVELS: `${BASE_PATH.TRAVELS}/favorite`,
  SIGNATURE_PREVIEW: `${BASE_PATH.SIGNATURE}/preview`,
};

 

 

2. api/request ๊ฐ€์„œ ํŒŒ์ผ ๋งŒ๋“ค๊ณ  ์•„๊นŒ ๋งŒ๋“  ๊ฒฝ๋กœ ๋„ฃ์–ด์ฃผ๊ธฐ

import { axios, axiosWithToken } from '../api';
import { API_PATH } from '@/constants/path';

// ํ† ํฐ์ด ํ•„์š”์—†๋Š” ๊ฒฝ์šฐ axios๋ฅผ ์“ฐ๋ฉด๋ฉ๋‹ˆ๋‹ค.
const getSignaturePreview = () => {
  return axios.get(API_PATH.SIGNATURE_PREVIEW);
};

// ํ† ํฐ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ axios๋Œ€์‹ , axiosWithToken์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

export { getSignaturePreview };

 

3. handler ๋งŒ๋“ค์–ด์„œ mockData ๋„ฃ์–ด์ฃผ๊ธฐ

import { HttpResponse, http } from 'msw';

import { baseURL } from '@/apis/api';
import { API_PATH } from '@/constants/path';

export const PreveiewHandlers = [
  http.get(`${baseURL}${API_PATH.SIGNATURE_PREVIEW}`, (req, res, ctx) => {
    const previewData = [
      {
        id: 1,
        userImgUrl: '<https://i.ibb.co/JdGMYqf/Group-1000000912.png>',
        date: '23 / 10 / 11',
        previewUrl:
          '<https://i.ibb.co/D1bwz3j/Kakao-Talk-20231203-204945606.png>" alt="Kakao-Talk-20231203-204945606',
        title: '์šฐ๋ฆฌ ๋™๊ธ€์ด์™€ ํ•จ๊ผํ•œ, ๊ฐ•๋ฆ‰ 1๋ฐ• 2์ผ',
        heart: 3012,
      },
      {
        id: 2,
        userImgUrl: '<https://i.ibb.co/JdGMYqf/Group-1000000912.png>',
        date: '23 / 10 / 11',
        previewUrl:
          '<https://i.ibb.co/D1bwz3j/Kakao-Talk-20231203-204945606.png>" alt="Kakao-Talk-20231203-204945606',
        title: '์šฐ๋ฆฌ ๋™๊ธ€์ด์™€ ํ•จ๊ผํ•œ, ๊ฐ•๋ฆ‰ 1๋ฐ• 2์ผ',
        heart: 3012,
      },
      {
        id: 3,
        userImgUrl: '<https://i.ibb.co/JdGMYqf/Group-1000000912.png>',
        date: '23 / 10 / 11',
        previewUrl:
          '<https://i.ibb.co/D1bwz3j/Kakao-Talk-20231203-204945606.png>" alt="Kakao-Talk-20231203-204945606',
        title: '์šฐ๋ฆฌ ๋™๊ธ€์ด์™€ ํ•จ๊ผํ•œ, ๊ฐ•๋ฆ‰ 1๋ฐ• 2์ผ',
        heart: 3012,
      },
      {
        id: 4,
        userImgUrl: '<https://i.ibb.co/JdGMYqf/Group-1000000912.png>',
        date: '23 / 10 / 11',
        previewUrl:
          '<https://i.ibb.co/D1bwz3j/Kakao-Talk-20231203-204945606.png>" alt="Kakao-Talk-20231203-204945606',
        title: '์šฐ๋ฆฌ ๋™๊ธ€์ด์™€ ํ•จ๊ผํ•œ, ๊ฐ•๋ฆ‰ 1๋ฐ• 2์ผ',
        heart: 3012,
      },
    ];
    return HttpResponse.json(previewData);
  }),
];

 

4. mocks>index.js ์—์„œ ์•„๊นŒ ๋งŒ๋“  ํ•ธ๋“ค๋Ÿฌ import ํ•ด์ฃผ๊ณ  ๋’ค์— ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋กœ ์ด์–ด์ฃผ๊ธฐ

import { PreveiewHandlers } from './previewHandler';
import { travelHandlers } from './travel-place';

export const handlers = [...travelHandlers, ...PreveiewHandlers];

 

< ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ >

์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ ๊ฐ€์„œ ๋งŒ๋“  api/request import ํ•ด์ฃผ๊ณ  ๋ฐ์ดํ„ฐ ์“ฐ๋ฉด ๋จ

import { getSignaturePreview } from '@/apis/request/preview';

const [data, setData] = useState([]);
  const getData = async () => {
    try {
      const res = await getSignaturePreview();
      const mockData = res.data;
      setData(mockData);
      console.log(data);
    } catch (e) {
      console.log(e);
    }
  };

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

 

EX)

import React, { useEffect, useState } from 'react';
import styled from 'styled-components';

import SignaturePreview from '../components/SignaturePreview';
import { getSignaturePreview } from '@/apis/request/preview';

export default function MySignature() {
  const [data, setData] = useState([]);
  const getData = async () => {
    try {
      const res = await getSignaturePreview();
      const mockData = res.data;
      setData(mockData);
      console.log(data);
    } catch (e) {
      console.log(e);
    }
  };

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

  return (
    <Wrap>
      <SignaturePreview {...data[0]} />
      <SignaturePreview {...data[1]} />
    </Wrap>
  );
}

const Wrap = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
`;

https://tech.kakao.com/2021/09/29/mocking-fe/

 

Mocking์œผ๋กœ ์ƒ์‚ฐ์„ฑ๊นŒ์ง€ ์ฑ™๊ธฐ๋Š” FE ๊ฐœ๋ฐœ

์•ˆ๋…•ํ•˜์„ธ์š”, ์นด์นด์˜ค์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ๊ฒ€์ƒ‰ํ”Œ๋žซํผํ”„๋ก ํŠธํŒŒํŠธ์˜ Lawrence.net์ž…๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ์—…๋ฌด์˜ ํšจ์œจ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์˜ ํ•˜๋‚˜๋กœ ๊ณ ๋ฏผํ•ด ๋ณธ Mocking์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ณ  ์ด๋ฅผ ์ ์šฉํ–ˆ๋˜ ์‚ฌ๋ก€

tech.kakao.com

 

https://velog.io/@khy226/msw%EB%A1%9C-%EB%AA%A8%EC%9D%98-%EC%84%9C%EB%B2%84-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

MSW(Mock Service Worker)๋กœ ๋”์šฑ ์ƒ์‚ฐ์ ์ธ FE ๊ฐœ๋ฐœํ•˜๊ธฐ

MSW(Mock Service Worker)๋Š” Service Worker๋ฅผ ์ด์šฉํ•ด ์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ์‹ค์ œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ(intercept) ๋ชจ์˜ ์‘๋‹ต (Mocked response)๋ฅผ ๋ณด๋‚ด์ฃผ๋Š” API Mocking ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

velog.io

 

 

728x90