storybook-addon-vite-mock
在 Storybook 上提供類似 jest.mock
的模組模擬功能。
使用方式
已將 'storybook-addon-vite-mock' 加入 Storybook 擴充套件。僅在使用 Webpack 作為建構器時有效。
擴充套件選項
啟用 include 和 exclude 以用於使用 Babel 的 storybook build
。不使用於 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()
的回傳值。
在 Story 顯示完成後,會自動執行 mockRestore()
。
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.dev.org.tw/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.dev.org.tw/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.dev.org.tw/docs/writing-docs/autodocs
tags: ['autodocs'],
// More on argTypes: https://storybook.dev.org.tw/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.dev.org.tw/docs/essentials/actions#action-args
args: {
onClick: () => {
fn();
},
},
};
// More on writing stories with args: https://storybook.dev.org.tw/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);
},
};