
msw λ service worker λ₯Ό μ΄μ©ν΄μ API λ₯Ό mocking νλ λΌμ΄λΈλ¬λ¦¬ μ λλ€. λ€νΈμν¬ μμ²μ κ°λ‘μ±λλ‘ μ€κ³λ Service Worker APIλ₯Ό νμ©νκΈ° λλ¬Έμ Mock μ¬μ© μ¬λΆ κ΄κ³ μμ΄ λμΌν μ ν리μΌμ΄μ λμμ 보μ₯νκ² λ©λλ€.
μ΄μ νμ¬μμ ν¬κ² 2κ°μ§μ λΆνΈν¨μ λκ»΄μ msw λ₯Ό λμ νκ² λμμ΅λλ€.
κΈ°λ₯μ κ°λ°νλ κ³Όμ μμ μλ²μ API λ₯Ό κΈ°λ€λ¦¬λ μΌμ΄ μ¦μμ‘κ³ , μ΄μ© μ μμ΄ λ³λͺ©νμμ΄ λ°μνκ² λμμ΅λλ€. κ·Έλ¦¬κ³ κΈ°λ€λ¦° νμ λ°μ API κ° μμνλ λΆλΆκ³Ό λ¬λΌμ§λ κ²½μ°κ° λ€λ°μ¬μκ³ , κΈ°λ₯ κ°λ°μ μλ€λ‘ λΆνμν μκ°μ΄ λλΉλμ΄μ ν΄λΉ λΆλΆμ μ€μ΄κΈ° μν΄μ λμ μ μλνμ΅λλ€.
ν μ€νΈμ λν νμμ±μ΄ λμ΄λλ©΄μ μ½λλ₯Ό μμ±νκΈ° μμνλλ° , νμν λ°μ΄ν°λ₯Ό μ§μ mocking ν΄μ νλ©΄μ μΆκ°νμ΅λλ€. μ΄κ² μ²μμλ ꡬνμ΄ μ½κ³ λΉ¨λΌμ λμ νλλ° , μ μ νλ‘μ νΈμ λ³Όλ₯¨μ΄ 컀μ§κ² λλ©΄μ μ€λ³΅λλ mockingμ΄ λμ΄λκ³ λ€νΈμν¬ μλ΅ μνμ λ°λΌμ λμνλ κ²½μ°μ λμμ΄ νλ€μ΄μ§κ² λμμ΅λλ€. μ΄ μκΈ°μ storybook λν ν¨κ» λμ νκΈ°λ‘ νλλ° , storybook μμλ mockingμ κ΄λ ¨ν΄ λΉμ·ν λ¬Έμ κ° λ°μνμ΅λλ€.
μ λ κ°μ§μ λΆνΈν μ μΌλ‘ msw λμ νκ² λμκ³ , μ€μ API κ° λμνλ κ²μ²λΌ mockingμ΄ κ°λ₯ν΄μ http method λ μλ΅ μνμ λ°λΌμ κ°κ° λμνκΈ°κ° μ¬μμ‘μ΅λλ€. λν λΆνμνκ² μ€λ³΅λλ mocking λ€μ΄ μ κ±°λκ³ , νλλ‘ ν©μ³μ§λ€λ³΄λ μ½λκ° κ°κ²°νκ³ μ¬μμ‘μ΅λλ€. λ€λ§ μ΄κΈ°μ μλ²λ₯Ό ꡬμΆνλλ° κ³΅μκ° λ§μ΄ λ€μ΄κ°κΈ΄ νμ§λ§ , νλ² κ΅¬μΆνκ² λλ©΄ κ·Έ μ΄νμ μ μ©μ΄ μ¬μμ μ€νλ € 곡μλ₯Ό μλ κ² κ°λ€λ μκ°μ΄ λλλ€.
shell
// msw μ€μΉ npm install -D msw λλ yarn add -D msw // λΈλΌμ°μ μμ μ¬μ©ν μ μλ μλΉμ€ μ컀 μ½λλ₯Ό λ§λ€κΈ° μν¨ npx msw init public/ --save
npx msw init public/ --save λ₯Ό μ§ννκ² λλ©΄ root κ²½λ‘μ μλμ κ°μ΄ mockServiceWorker.js νμΌμ΄ μκΈ°κ² λ©λλ€. ν΄λΉ νμΌμ λΈλΌμ°μ μμ mocking μ μν΄ μ¬μ©ν μ μλ serviceWorker λ‘ μ¬μ©λ©λλ€.

κΈ°λ³Έμ μΌλ‘ msw μ ꡬ쑰λ 3κ°μ§λ‘ λλμ΄μ§λλ€.
rest API started graphQL started
API mocking μ μ§μ νλ νμΌλ€ μ λλ€. mocking ν method , url , response κ° λ±μ μ€μ ν μ μμ΅λλ€.
ts
// src/mock/handlers/mock.ts
import { HttpResponse, http } from 'msw'; // <- graphQL μ¬μ©μ graphQL μ¬μ©
export const mockHandler = [
http.get('/fake', () => {
return HttpResponse.json({
data: 'data1',
});
}),
];
const handlers = [...mockHandler];
export default handlers;
http : rest API μ μ¬μ©λλ ν¨μμ
λλ€. ( μ΄μ λ²μ μμλ rest λ‘ μ¬μ©λμμ§λ§ , νμ¬λ http λ‘ μμ λμμ΅λλ€. ) κ·Έ λ€μ method μ url μ μν©μ λ§μΆ° μ€μ ν μ μμ΅λλ€.HttpResponse : response λ₯Ό mocking ν μ μμ΅λλ€. μν©μ λ§μΆ° μνλ dataλ₯Ό μμ ν μ μμ΅λλ€.κ·Έ μΈμ post , delete λ±λ±λ mocking κ°λ₯ν©λλ€. ν΄λΉ λΆλΆμ 곡μλ¬Έμμμ νμΈκ°λ₯ν©λλ€. μ νμΌλ€ μ€ browser λλ server μμ msw μ¬μ© μ νμν λΆλΆλ§ κ°μ Έμμ μ¬μ©κ°λ₯ν©λλ€.
ts
// src/mock/server.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);
node νκ²½μμ μ€νλλλ‘ μ€μ ν©λλ€. μ handlers μ μλ mock API λ€μ΄ μ€νλ©λλ€. λλΆλΆ ν
μ€νΈ νκ²½ ( jest , vitest λ± ) μμ μ€νλ©λλ€. μ΄ν jest.setup.tsx νμΌ λ±μμ server λ₯Ό μ°κ²° ν ν
μ€νΈμμ mock api λ₯Ό μ¬μ©ν μ μμ΅λλ€.
ts
// src/mock/browsers.ts
import { setupWorker } from 'msw/browser';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
setupWorker : browser μμ μ¬μ© κ°λ₯νλλ‘ workerλ₯Ό μ€μ ν©λλ€. ( μ΄μ λ²μ μμλ msw μμ λ°λ‘ import κ°λ₯νμ§λ§ , νμ¬ λ²μ μμλ msw/browser μμ import ν©λλ€. )handlers : μμμ μ€μ ν handlers μ€ νμν λΆλΆμ setupWorker μ λ£μ΄μ μ€ν κ°λ₯ν©λλ€. ν΄λΉ worker λ΄λΆλ‘ λ€μ΄κ° handlers λ browser λλ storybook μ€ν μ mocking λ©λλ€.μ΄ν νμΌ μ€νλλ main νμΌμμ worker λ₯Ό μ€νν΄ μ€λλ€.
ts
// src/main.tsx
const enableMocking = async () => {
if (process.env.NODE_ENV !== 'development') {
return;
}
const { worker } = await import("./mocks/browser");
return worker.start();
};
enableMocking().then(() => {
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
});
APPμ΄ μ€νλ λ msw κ° μ€νλλλ‘ μ€μ ν μ μμ΅λλ€. 곡μ λ¬Έμ μμλ service worker λ±λ‘μ λΉλκΈ°μμ΄λ―λ‘ μ λ°©λ²μ μΆμ²νκ³ μμ΅λλ€. μ΄ν μ±μ μ€ννκ² λλ©΄

μ½μμ μμ²λΌ [MSW] Mocking enabled κ° λ±μ₯νλ€λ©΄ , μ μμ μΌλ‘ μ°κ²°λ κ²μ μ μ μμ΅λλ€.
μ΄μ μ μ μ©νμ λμ λ²μ μ΄ λ¬λΌμ μ½κ° ν€λ© λΆλΆμ΄ μμμ§λ§ , 곡μλ¬Έμμμ μ μ€λͺ ν΄μ£Όκ³ μμ΄μ μ½κ² λ΅μ μ°Ύμ μ μμμ΅λλ€. λ€μ κΈμμλ msw λ₯Ό μ΄μ©ν test μ storybook μμ±μ μ΄μΌκΈ° νλ €κ³ ν©λλ€.
μλͺ»λ λΆλΆμ΄ μμΌλ©΄ μλ €μ£Όμλ©΄ κ°μ¬λλ¦¬κ² μ΅λλ€. μ μμ μ΄ μλ repo λ μ¬κΈ°λ₯Ό νμΈν΄μ£ΌμΈμ !