⚠️ 重要提示:此包已弃用,Storybook 也已不再支持 Vue2。如果您不打算升级到 Vue 3,则可以继续使用 Storybook 7。composeStories API 已在 Storybook 8 中提升为一等 Storybook 功能,您现在可以将其用作 @storybook/vue3 的一部分。更多信息:https://github.com/storybookjs/testing-vue3/issues/16
⚠️ 如果您正在将 Storybook 与 **Vue 3** 一起使用,请改用 @storybook/testing-vue3!
安装
此库应作为项目 devDependencies
中的一个依赖项安装
通过 npm
npm install --save-dev @storybook/testing-vue
或通过 yarn
yarn add --dev @storybook/testing-vue
设置
Jest 配置
如果您使用 Jest 运行测试,则应在您的 jest.config.js
中将 .vue
文件映射到使用包含其模板编译器的 Vue 版本。
moduleNameMapper: {
'^vue$': 'vue/dist/vue.common.dev.js'
},
Storybook CSF
此库要求您使用 Storybook 的 组件故事格式 (CSF) 和 提升的 CSF 注解,这是从 Storybook 6 开始编写故事的推荐方法。
从本质上讲,如果您的故事看起来与此类似,那么您就可以开始了!
// CSF: default export (meta) + named exports (stories)
export default {
title: 'Example/Button',
component: Button,
};
export const Primary = () => ({
template: '<my-button primary />',
});
全局配置
这是一个可选步骤。如果您没有使用 全局装饰器,则无需执行此操作。但是,如果您确实使用了,则这是应用全局装饰器的必要步骤。
如果您有全局装饰器/参数等,并希望在测试故事时应用它们,则首先需要进行设置。您可以通过添加到或创建 Jest 设置文件 来实现。
// setupFile.js <-- this will run before the tests in jest.
import { setGlobalConfig } from '@storybook/testing-vue';
import * as globalStorybookConfig from './.storybook/preview'; // path of your preview.js file
setGlobalConfig(globalStorybookConfig);
为了让 Jest 拾取设置文件,您需要在测试命令中将其作为选项传递。
// package.json
{
"test": "jest --setupFiles ./setupFile.js"
}
用法
composeStories
composeStories
将处理您指定的组件中的所有故事,组合所有故事中的参数/装饰器,并返回包含组合故事的对象。
如果您使用组合故事(例如 PrimaryButton),则组件将使用故事中传递的参数进行渲染。但是,您可以自由地在组件之上传递任何道具,并且这些道具将覆盖故事参数中传递的默认值。
import { render, screen } from '@testing-library/vue';
import { composeStories } from '@storybook/testing-vue';
import * as stories from './Button.stories'; // import all stories from the stories file
// Every component that is returned maps 1:1 with the stories, but they already contain all decorators from story level, meta level and global level.
const { Primary, Secondary } = composeStories(stories);
test('renders primary button with default args', () => {
render(Primary());
const buttonElement = screen.getByText(
/Text coming from args in stories file!/i
);
expect(buttonElement).not.toBeNull();
});
test('renders primary button with overriden props', () => {
render(Secondary({ label: 'Hello world' })); // you can override props and they will get merged with values from the Story's args
const buttonElement = screen.getByText(/Hello world/i);
expect(buttonElement).not.toBeNull();
});
composeStory
如果您希望将其应用于单个故事而不是所有故事,则可以使用 composeStory
。您需要将元数据(默认导出)也传递进去。
import { render, screen } from '@testing-library/vue';
import { composeStory } from '@storybook/testing-vue';
import Meta, { Primary as PrimaryStory } from './Button.stories';
// Returns a component that already contain all decorators from story level, meta level and global level.
const Primary = composeStory(PrimaryStory, Meta);
test('onclick handler is called', async () => {
const onClickSpy = jest.fn();
render(Primary({ onClick: onClickSpy }));
const buttonElement = screen.getByRole('button');
buttonElement.click();
expect(onClickSpy).toHaveBeenCalled();
});