storybook-addon-vite-mock
在 Storybook 上提供类似 jest.mock
的模块模拟功能。
用法
将 'storybook-addon-vite-mock' 添加到 Storybook 插件中。仅在构建器使用 Webpack 时有效。
插件选项
在使用 Babel 的 storybook build
中启用了 include 和 exclude。在 storybook dev
中未使用。
如果省略 include,则所有模块都将被覆盖。
addons: [
{
name: 'storybook-addon-vite-mock',
options: {
//ignore 'abc.js'
exclude: (id)=>id==="abc.js",
}
}
],
Storybook@8 & @storybook/react-vite
- .storybook/main.ts
import { mergeConfig } from 'vite';
import { viteMockPlugin } from 'storybook-addon-vite-mock';
/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-onboarding',
'@storybook/addon-links',
'@storybook/addon-essentials',
'@chromatic-com/storybook',
'@storybook/addon-interactions',
'storybook-addon-vite-mock', // Add this line
],
framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {
autodocs: 'tag',
},
};
export default config;
示例 1
test.ts
export const Test = () => 'Test';
Button.tsx
import React from 'react';
import PropTypes from 'prop-types';
import './button.css';
import { Test } from './test';
/**
* Primary UI component for user interaction
*/
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (
<button
type="button"
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
style={backgroundColor && { backgroundColor }}
{...props}
onClick={() => {
props.onClick();
}}
>
{label}
<div>
{
// insert mock here
Test()
}
</div>
</button>
);
};
Button.propTypes = {
/**
* Is this the principal call to action on the page?
*/
primary: PropTypes.bool,
/**
* What background color to use
*/
backgroundColor: PropTypes.string,
/**
* How large should the button be?
*/
size: PropTypes.oneOf(['small', 'medium', 'large']),
/**
* Button contents
*/
label: PropTypes.string.isRequired,
/**
* Optional click handler
*/
onClick: PropTypes.func,
};
Button.defaultProps = {
backgroundColor: null,
primary: false,
size: 'medium',
onClick: undefined,
};
Button.stories.ts
createMock
使用 jest.fn()
的返回值替换目标模块函数。mockRestore()
会在 Story 显示完成后自动执行。
import { fn } from '@storybook/test';
import { StoryObj } from '@storybook/react';
import { Button } from './Button';
import { Test } from './test';
import { createMock, getMock, render } from 'storybook-addon-vite-mock';
// More on how to set up stories at: https://storybook.org.cn/docs/writing-stories#default-export
export default {
title: 'Example/Button',
component: Button,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.org.cn/docs/configure/story-layout
layout: 'centered',
moduleMock: {
mock: () => {
const mock = createMock(Test);
return [mock];
},
},
},
// This component will have an automatically generated Autodocs entry: https://storybook.org.cn/docs/writing-docs/autodocs
tags: ['autodocs'],
// More on argTypes: https://storybook.org.cn/docs/api/argtypes
argTypes: {
backgroundColor: { control: 'color' },
},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.org.cn/docs/essentials/actions#action-args
args: {
onClick: () => {
fn();
},
},
};
// More on writing stories with args: https://storybook.org.cn/docs/writing-stories/args
export const Primary: StoryObj = {
args: {
primary: true,
label: 'Button',
},
play: async ({ parameters }) => {
const mock = getMock(parameters, Test);
mock.mockReturnValue('Primary');
render(parameters);
},
};
export const Secondary = {
args: {
label: 'Button',
},
play: async ({ parameters }) => {
const mock = getMock(parameters, Test);
mock.mockReturnValue('Secondary');
render(parameters);
},
};
export const Large = {
args: {
size: 'large',
label: 'Button',
},
play: async ({ parameters }) => {
const mock = getMock(parameters, Test);
mock.mockReturnValue('Large');
render(parameters);
},
};
export const Small = {
args: {
size: 'small',
label: 'Button',
},
play: async ({ parameters }) => {
const mock = getMock(parameters, Test);
mock.mockReturnValue('Small');
render(parameters);
},
};