본문 바로가기
SPA/Next

[Next] Next13 이후로 MSW 사용하기 (3) - Storybook에서 사용하기

by J4J 2024. 1. 9.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 next13 이후로 msw 사용하기 마지막인 storybook에서 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

관련 글

 

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

[React] MSW로 API Mocking 하기 (4) - Storybook에서 사용하기

 

 

반응형

 

 

이전 글

 

[Next] Next13 이후로 MSW 사용하기 (1) - Browser 환경 설정

[Next] Next13 이후로 MSW 사용하기 (2) - Node 환경 설정

 

 

 

 

들어가기에 앞서

 

들어가기에 앞서 storybook에 msw를 적용하기 위해서는 2가지 환경이 설정되어 있어야 합니다.

 

  • storybook 사용 환경
  • msw browser 사용 환경

 

 

 

storybook 사용 환경이 되어 있지 않으신 분은 [Next] Storybook으로 UI 컴포넌트 문서화하기 (1) - 기본 설정을 참고하시면 됩니다.

 

msw browser 사용 환경이 되어 있지 않으신 분은 [Next] Next13 이후로 MSW 사용하기 (1) - Browser 환경 설정을 참고하시면 됩니다.

 

 

 

 

설정 방법

 

[ 1. 패키지 설치 ]

 

$ npm install -D msw-storybook-addon

 

 

 

[ 2. preview 설정 추가 ]

 

storybook에서 사용되는 preview에 msw loader을 등록해줘야 합니다.

 

다음과 같이 설치한 패키지를 통해 활용할 수 있는 설정들을 해주시면 됩니다.

 

// .storybook/preview.ts
import { initialize, mswLoader } from 'msw-storybook-addon';

// msw 초기화
initialize();

const preview: Preview = {
    parameters: {
        ...
    },

    // msw addon loader 등록
    loaders: [mswLoader],
};

export default preview;

 

 

 

 

[ 3. main 설정 추가 ]

 

next에서 msw에 storybook을 적용할 때 mockServiceWorker가 담겨 있는 public 경로를 정적 디렉터리로 설정해줘야 합니다.

 

설정해주지 않으면 mockServiceWorker를 읽지 못하여 msw가 정상적으로 동작되지 않습니다.

 

// .storybook/main.ts
import type { StorybookConfig } from '@storybook/nextjs';

const config: StorybookConfig = {

    ...
    
    // 정적 디렉토리 설정 (mockServiceWorker 사용되기 위함)
    staticDirs: ['../public']
};
export default config;

 

 

 

[ 4. handler 등록 ]

 

API mocking 처리를 관리하는 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];

 

 

 

[ 5. preview에 handler 설정 ]

 

정의한 handler를 preview 파일에 추가해보겠습니다.

 

// .storybook/preview.ts
import { handlers } from '../src/mocks/handlers';

const preview: Preview = {
    parameters: {
    
        ...
        
        msw: {
            handlers: {
              ...handlers // msw handler 등록
            }
        }
    },
};

export default preview;

 

 

 

 

테스트

 

모든 설정을 마쳤다면 다음과 같이 테스트를 위한 코드를 작성해 보겠습니다.

 

// src/app/page.tsx
'use client';

import axios from 'axios';
import { useEffect, useState } from 'react';

export default function RootPage() {
    const [names, setNames] = useState<string[]>([]);

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

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

    return (
        <main className="m-4">
            <h2 className="text-2xl font-bold">Storybook Names ...</h2>

            <div>
                <ul>
                    {names.map((name) => (
                        <li key={name} data-testid="name-list-item">
                            {name}
                        </li>
                    ))}
                </ul>
            </div>
        </main>
    );
}


// src/app/page.stories.tsx
import { Meta, StoryObj } from '@storybook/react';
import RootPage from './page';

const meta: Meta<typeof RootPage> = {
    title: 'Default/RootPage',
    component: RootPage,
};

export default meta;
type Story = StoryObj<typeof RootPage>;

export const Default: Story = {
    args: {},
};

 

 

 

 

코드를 작성했다면 스토리북을 실행하여 올바르게 msw를 이용하여 API mocking을 수행하는지 확인해 보겠습니다.

 

stories 파일에 설정한 meta 정보를 기반으로 페이지에 접근해 보면 다음과 같이 mocking 한 결과와 동일한 데이터가 보이는 것을 확인할 수 있습니다.

 

storybook msw API mocking 적용

 

 

 

 

 

 

 

 

이상으로 next13 이후로 msw 사용하기 마지막인 storybook에서 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글