๊ฐ์
ํ๋ก์ ํธ๋ฅผ ํ๋ฉด, ํญ์ ํ๋ก ํธ๋ง ํ์ ์ ์ผ ๋ง์ง๋ง ์๊ฐ๊น์ง ๊ฐ๋ฐ์ ํ๊ณ ์๋ค..
๊ธฐํ, ๋์์ธ์ด ์๋ฃ๋๋ฉด ๋ฐฑ์๋๊ฐ ๋จผ์ ๊ฐ๋ฐ์ ์์ํ๊ณ , API ๊ฐ๋ฐ์ด ๋๋ ๋ค ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ด ๋ค์ด๊ฐ๋ฉด ์ข๊ฒ ์ง๋ง, ํ์ค์ ๋ฐฑ์๋์ ํ๋ก ํธ์๋๊ฐ ๋์์ ์์ํ๋ ๊ฒ ๋๋ถ๋ถ์ด๋ค.
๊ทธ๋์ ํ๋ก ํธ์์๋ ๋ฐฑ์๋๊ฐ ์ค API ๋ช ์ธ์๋ฅผ ๋ณด๊ณ Mock Data๋ฅผ ๋ง๋ค์ด์ ๋ฐ์ดํฐ๋ฅผ ๋์ธ ์ค๋น๋ฅผ ํด๋๋๋ค. ํ์ง๋ง ์ด๋ฐ ์์ผ๋ก ํ๋ฉด, API ๊ฐ๋ฐ์ด ๋๋ ๋ค, ๋ ๋ง์ง๋ง๊น์ง ์ธ๋กญ๊ฒ ๊ฐ๋ฐ์ ํด์ผํ๋ค..ใ ใ
์ด๋ฒ์ ๋ฐฉํ UMC ํ๋ก์ ํธ๋ฅผ ์์ํ๋ฉด์ ํ๋ก ํธ์๋์์ MSW๋ฅผ ์ฌ์ฉํด๋ณด์๋ ์๊ธฐ๊ฐ ๋์๋ค. MSW๋ง ์ ๋๋ก ๊ตฌ์ถํด๋์ผ๋ฉด, API ์ฐ๊ฒฐ์ ๋ฏธ๋ฆฌ ํด๋๋ ๊ฒ๊ณผ ๋๊ฐ์์ ๋์ค์ ๋ ๊ฐ๋ฐ์ ํ์ง ์์๋ ๋๋ค๊ณ ํ๋ค. ์ด๋ฒ ํ์ ์์๋ ๋ฐฑ์๋๋ณด๋ค ๊ฐ๋ฐ์ ๋ ๋นจ๋ฆฌ ๋๋ด๋ณด์~><
1. MSW(Mock Service Worker)๋?
MSW๋ API Mocking ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, Service Worker๋ฅผ ์ฌ์ฉํด์ ์๋ฒ ์์ฒญ์ ์ค๊ฐ์์ ๊ฐ๋ก์ฑ์ mock response๋ฅผ ๋๋ ค์ค๋ค.
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
- 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
MSW(Mock Service Worker)๋ก ๋์ฑ ์์ฐ์ ์ธ FE ๊ฐ๋ฐํ๊ธฐ
MSW(Mock Service Worker)๋ Service Worker๋ฅผ ์ด์ฉํด ์๋ฒ๋ฅผ ํฅํ ์ค์ ๋คํธ์ํฌ ์์ฒญ์ ๊ฐ๋ก์ฑ์(intercept) ๋ชจ์ ์๋ต (Mocked response)๋ฅผ ๋ณด๋ด์ฃผ๋ API Mocking ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
velog.io