4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ReactでmswとStoryBookを連携する

Last updated at Posted at 2022-06-23

前提

前回のこちらの記事の続編になります。msw自体の説明や後述のコードはこちらを参考にしてください。

StoryBookとは

Storybookは、UIコンポーネントとページを分離して構築するためのオープンソースツールです。UIの開発、テスト、およびドキュメント化に活用することができます。動作イメージや仕様については以下の公式を参考ください。

StoryBookの環境準備

StoryBookCLIのCLIをインストールします。

npm install -g @storybook/cli

StoryBook環境の初期化を行います。

npx sb init

StoryBookを起動します。実行のコマンドは環境によってことなりますが、上記コマンドの最後に出力されると思います。以下はcreate-react-app+npmの環境の場合です。

npm run storybook

create-react-appで作成したプロジェクトでは@storybook/preset-create-react-appのバージョンが低いと失敗したので、エラーが発生した場合、package.jsonを以下のように修正し、再度npm i を実行してください。

"@storybook/preset-create-react-app": "^4.0.0",

起動後のブラウザで以下のようなデフォルトのストーリーファイル(Button,Header,Page)が表示されます。

reactmswstorybook1.png

msw連携

storybook起動時にmswのServiceWorker起動

mswとmswのstorybookの連携アドオンをインストールします

npm i -D msw msw-storybook-addon

mswのServiceWorkerを設定します。(前回の記事で設定していればスキップ可能です)

npx msw init public/ --save

.storybook/preview.js にプラグインを追加し、起動するようにします。

import { initialize, mswDecorator } from "msw-storybook-addon";

// Initialize MSW
initialize();

// Provide the MSW addon decorator globally
export const decorators = [mswDecorator];

.storybook/main.js を以下のように書き換えます。

module.exports = {
  ...
  staticDirs: ["../public"],  //追加
};

package.jsonを以下のように書き換えます。(-sオプションは6.4以降でdeprecatedなので消します)

"scripts": {
        ・・・
    "storybook": "start-storybook -p 6006", //変更箇所
    "build-storybook": "build-storybook" //変更箇所
},

この時点で一度起動(npm run storybook)します。mswのServiceWorkerの起動に成功するとブラウザのコンソールログに以下のようなメッセージが表示されます。

reactmswstorybook2.png

ストーリーファイルからmswのAPIモックを呼び出す

前回作成したコンポーネント(UserList.tsx)に対するストーリーファイル(UserList.stories.tsx)を作成します。
前回カスタムフックのテスト用に作成したAPIモック(mocks/handlers.ts)をそのまま使うことができます。異常系のように普段のAPIと違う挙動をしたい場合、parameterを上書きすることもできます。

import { handlers } from "../mocks/handlers";
import { rest } from "msw";
import UserList from "./UserList";

export default {
  title: "UserList",
  component: UserList,
};

export const SuccessBehavior = () => <UserList />;

SuccessBehavior.parameters = {
  // 正常系は定義済みのhandlersをそのまま利用
  msw: {
    handlers: handlers,
  },
};

export const FailureBehavior = () => <UserList />;

FailureBehavior.parameters = {
  // 異常系はhandlersを上書き
  msw: {
    handlers: [
      rest.get("/api/users", (req, res, ctx) => {
        return res(ctx.status(500), ctx.json({ message: "Internal Server Error" }));
      }),
    ],
  },
};

ストーリーファイルの作成場所を変更した場合、.storybook/main.jsも変更します。

module.exports = {
  // stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  stories: ["../src/components/**/*.stories.@(js|jsx|ts|tsx)"], //components配下に移動した場合
  ...

再度storybookを起動します。(main.js等を書き換えた場合、再起動が必要です)

npm run storybook

StoryBook上で通信結果に応じた表示を確認することができました。

  • API通信成功時に表示されるコンポーネント(コンソールには200 OK)

reactmswstorybook3.png

  • API通信失敗時に表示されるコンポーネント(コンソールには500 Internal Error)

reactmswstorybook4.png

感想

前回のテストにmswを導入するだけではメリットを感じにくかったですが、こうやってStoryBookのデータ連携でも簡単に使えるとモチベーションがあがりました。StoryBook自体まだまだ初心者なので色々覚えていきたいと思います。

参考

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?