😶🌫️
StorybookでServerComponentの処理をモックする
Storybookを使ってコンポーネントを管理する際に、ServerComponent内部で fetch
やDBアクセスをしているコンポーネントがあった時に処理をモックする方法を紹介します。モックにせずともPresenterのような処理と表示を物理的にコンポーネントを分ける方法もありますが、Storybookのためだけに分離させるのは微妙なこともあるので今回はモックにします。
利用するのは storybook-addon-module-mock
というアドオンです。これを使うと jest.mock
のように柔軟なモックを作ることができます。
npm install -D storybook-addon-module-mock
利用パッケージとバージョン
- Storybook : 8.5.4
- storybook-addon-module-mock : 1.3.4
- Next.js : 15.1.7
Storybookの設定
-
storybook-addon-module-mock
アドオンの有効化 - 今回はNext.jsを利用しているので
@storybook/nextjs
を指定 -
experimentalRSC
でReact Server Componentのサポートを有効化- 有効にしないと
async/await
コンポーネントが動きません
- 有効にしないと
.storybook/main.ts
import type { StorybookConfig } from "@storybook/nextjs";
const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
{
name: "storybook-addon-module-mock",
options: {},
},
],
framework: {
name: "@storybook/nextjs",
options: {},
},
staticDirs: ["../public"],
features: {
experimentalRSC: true,
},
};
export default config;
StoryでMockの指定
対象コンポーネント
-
fetchData
がデータフェッチをするバックエンド側の処理です
MyServerComponent.tsx
import { fetchData } from "@/stories/fetchData";
export async function MyServerComponent() {
const data = await fetchData();
return (
<div>
Server Component {data.firstName} {data.lastName}
</div>
);
}
fetchData.ts
export async function fetchData() {
// 本来はDBリクエストや外部APIをfetchする
return { firstName: "foo", lastName: "bar" };
}
StoryでMock
-
parameters.moduleMock
でモックにしたい関数を指定します -
mockImplementation
で任意の値を返す処理に差し替えが可能です
MyServerComponent.stories.ts
import type { Meta, StoryObj } from "@storybook/react";
import * as mock from "@/stories/fetchData";
import { createMock } from "storybook-addon-module-mock";
import { MyServerComponent } from "./MyServerComponent";
const meta: Meta<typeof MyServerComponent> = {
component: MyServerComponent,
parameters: {
moduleMock: {
mock: () => {
const fetchData = createMock(mock, "fetchData");
fetchData.mockImplementation(async () => {
return { firstName: "John", lastName: "Doe" };
});
return [fetchData];
},
},
},
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {},
};
以上でStorybookでデータフェッチなどを行うServer Componentの処理をモックできます。簡単ですね。
Discussion