0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【msw】APIをStorybookでモックしてテストしてみる

Posted at

はじめに

こんにちは、エンジニアのkeitaMaxです。

今回はmswを使用してStorybookでAPIを呼び出すテストを書いていこうと思います。

Laravel10,Inertia.js,React,Storybookを使用します。

インストール

以下コマンドでインストールします。

npm install msw@latest --save-dev
npm i msw msw-storybook-addon -D

mswの初期設定

以下コマンドで初期設定します。

まずmswファイルをpublicと同じ階層に作成します。

その後以下のコマンドを実行します。

npx msw init msw/ --save

するとmswフォルダ配下にmockServiceWorker.jsファイルが作成されます。

※これしないと、以下のようにbuildする時に怒られます。

(!) The public directory feature may not work correctly. outDir /Users/niheikeita/develop/real-estate-search-app/src/public/build and publicDir /Users/niheikeita/develop/real-estate-search-app/src/public are not separate folders.

Storybookの設定

preview.tsの設定

以下のようにloaders: [mswLoader],を追加します。

preview.ts
import type { Preview } from "@storybook/react";
import "../resources/css/app.css";
import { initialize, mswLoader } from 'msw-storybook-addon' // 追加

initialize()

const preview: Preview = {
    parameters: {
        controls: {
            matchers: {
                color: /(background|color)$/i,
                date: /Date$/i,
            },
        },
    },
    loaders: [mswLoader], // 追加
};

global.route = (name, params, absolute) => {
    return `/${name}`;
};

export default preview;

vite.config.jsの修正

vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.tsx',
            refresh: true,
        }),
        react(),
    ],
    publicDir: 'public', // 追加
});

※これ設定しないと以下のようにエラーが出るので注意してください。

Error: [MSW] Failed to register a Service Worker for scope ('http://localhost:6007/') with script ('http://localhost:6007/mockServiceWorker.js'): Service Worker script does not exist at the given path.
  at async startWorkerInstance (/node_modules/.cache/storybook/dd4df79305cd50a532e8ccaa21ee67a8cbbc890739d67fa2856713328caf1b91/sb-vite/deps/msw-storybook-addon.js?v=0d345a9a:1202:24))
  at async SetupWorkerApi.start (/node_modules/.cache/storybook/dd4df79305cd50a532e8ccaa21ee67a8cbbc890739d67fa2856713328caf1b91/sb-vite/deps/msw-storybook-addon.js?v=0d345a9a:2709:12))

テストの作成

実際にテストを書いてみます。

/api/uploadというAPIを読んでいるコンポーネントがあったので、それをモックしてみようと思います。

以下のようになります。

index.stories.tsx
import { Meta, StoryObj } from '@storybook/react';
import { UploadImageArea } from '.';
import { useState } from 'react';
import { HttpResponse, ResponseResolver, http } from 'msw';

const meta: Meta<typeof UploadImageArea> = {
    title: 'views/Admin/PropertyRegister/components/UploadImageArea',
    component: UploadImageArea,
    // 追加 ⇩ ⇩ ⇩ ⇩
    parameters: {
        msw: {
            handlers: [
                http.post('/api/upload', () => {
                    return HttpResponse.json({
                        test: 'Test',
                    })
                }),
            ],
        },
    },
    // 追加⇧⇧⇧⇧
    tags: ['autodocs'],
}
export default meta


type Story = StoryObj<typeof meta>

export const Test: Story = {
    render() {
        const [images, setImages] = useState<{ url: any; id: any; }[]>([]);
        return (
            <UploadImageArea
                images={images}
                onImageChange={setImages} />
        )
    },
}

これでnpm run storybookコマンドを叩いてtest: 'Test'というレスポンスが来ているか確認すると、しっかりと設定した値が返却されていることがわかります。

おわりに

StorybookだけだとAPIのテストができないということで困ったこともあったのですが、mswを使用すると簡単にテストができました。

今後も積極的に使用していきたいと思います。

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました!

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?