Mocking providers
组件可以通过 Context Provider 接收数据或配置。例如,一个 styled component 可能会从 ThemeProvider 访问其主题,或者 Redux 使用 React context 为组件提供对应用程序数据的访问。要 mock provider,你可以将你的组件包装在一个包含必要 context 的 decorator 中。
import React from 'react';
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Preview } from '@storybook/your-framework';
import { ThemeProvider } from 'styled-components';
const preview: Preview = {
decorators: [
(Story) => (
<ThemeProvider theme="default">
{/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it */}
<Story />
</ThemeProvider>
),
],
};
export default preview;请注意上面文件的扩展名(.tsx 或 .jsx)。根据你的项目设置,你可能需要调整你的 preview 文件的扩展名以允许使用 JSX。
有关另一个示例,请参阅 Intro to Storybook 教程的 Screens 章节,其中我们使用 mock data 来 mock Redux provider。
配置 mock provider
Mocking a provider时,可能需要配置 provider 为 individual stories 提供不同的值。例如,你可能希望使用不同的主题或用户角色来测试组件。
一种方法是单独定义每个 story 的 decorator。但是,如果你设想一种场景,你想为你的每个组件创建 light 和 dark 主题的 stories,这种方法很快就会变得很麻烦。
为了获得更好的方法,减少重复,你可以使用 decorator 函数的第二个 "context" 参数 来访问 story 的 parameters 并调整提供的值。这样,你就可以只定义一次 provider,并为每个 story 调整其值。
例如,我们可以调整上面的 decorator,使其读取 parameters.theme 来确定提供哪个主题
import React from 'react';
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Preview } from '@storybook/your-framework';
import { ThemeProvider } from 'styled-components';
// themes = { light, dark }
import * as themes from '../src/themes';
const preview: Preview = {
decorators: [
// 👇 Defining the decorator in the preview file applies it to all stories
(Story, { parameters }) => {
// 👇 Make it configurable by reading the theme value from parameters
const { theme = 'light' } = parameters;
return (
<ThemeProvider theme={themes[theme]}>
<Story />
</ThemeProvider>
);
},
],
};
export default preview;现在,你可以在你的 stories 中定义一个 theme parameter 来调整 decorator 提供的 theme
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta = {
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
// Wrapped in light theme
export const Default: Story = {};
// Wrapped in dark theme
export const Dark: Story = {
parameters: {
theme: 'dark',
},
};这种强大的方法允许你以一种灵活且可维护的方式为你的组件提供任何值(主题、用户角色、mock data 等)。
