#jestjs #next.js #react-testing-library #storybook
#jestjs #next.js #react-testing-library #сборник рассказов
Вопрос:
Я столкнулся с проблемой при интеграции моих историй в мои модульные тесты с использованием библиотеки тестирования Jest amp; React в приложении NextJS. В Storybook мои компоненты NextJS отображаются без проблем, при этом дополнение Storybook Next Router работает должным образом. Однако в моем тестовом файле Jest мой тест выдает ошибку, потому что useRouter() возвращает null. Я считаю, что я правильно настроил все дополнения.
Моя настройка:
- NextJS 12
- Библиотека тестирования Jest и React
- Сборник рассказов
- Дополнение Storybook Next Router (для использования следующего маршрутизатора внутри Storybook)
- @storybook /testing-реагировать (для интеграции моих историй, аргументов и параметров с библиотекой тестирования)
Проблема:
Я настроил все файлы в соответствии с документами. История отлично отображается внутри Storybook, а useRouter() работает благодаря дополнению Storybook Next. Однако composeStories()
функция из @storybook /testing-react, похоже, не может правильно инициализировать следующего поставщика маршрутизатора из первого дополнения. Мой модульный тест завершается ошибкой со следующей ошибкой:
Не удалось запустить
TypeError: не удается прочитать свойство ‘locale’ null
И указывает на следующую строку внутри моего компонента:
// Events.tsx
const { locale = 'en' } = useRouter();
Это мой тестовый файл:
// Events.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import { composeStories } from '@storybook/testing-react';
import * as stories from './Events.stories'
const { WithSeasonsAndEvents } = composeStories(stories);
describe('Events Screen', ()=> {
render(<WithSeasonsAndEvents />);
it('renders input data', ()=> {
// set up test
});
});
И мой файл stories:
// Events.stories.tsx
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import Events from './Events';
export default {
title: 'Events/Events Screen',
component: Events
} as ComponentMeta<typeof Events>;
const Template: ComponentStory<typeof Events> = (args) => <Events {...args} />;
export const WithSeasonsAndEvents = Template.bind({});
WithSeasonsAndEvents.args = {
// many args here
};
Эта история отлично отображается в Storybook. useRouter() работает, как и ожидалось, внутри моей истории, и я могу использовать все его свойства, включая pathname
и locale
. Однако по какой-то причине функция useRouter() возвращает null, когда составленная история отображается библиотекой тестирования React.
What I have tried:
- Verified installing @storybook/testing-react and set up my global configuration in jest setup file:
// jest-setup.ts
import '@testing-library/jest-dom/extend-expect';
import { setGlobalConfig } from '@storybook/testing-react';
// Storybook's preview file location
import * as globalStorybookConfig from './.storybook/preview';
setGlobalConfig(globalStorybookConfig);
- Verified that jest reads my setup file and finds my Storybook preview file
- Verified both .storybook/preview.js and .storybook/main.js match the usage guide:
preview.js
// .storybook/preview.js
import '../styles/tailwind.css';
import { RouterContext } from "next/dist/shared/lib/router-context"; // next 12 https://storybook.js.org/docs/react/writing-stories/parameters
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
nextRouter: {
Provider: RouterContext.Provider,
locale: 'en',
},
}
main.js
// .storybook/main.js
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)",
"../components/**/*.stories.@(js|jsx|ts|tsx|mdx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"storybook-addon-next-router",
],
"framework": "@storybook/react"
}
- Истории отлично отображаются в Storybook, все функции useRouter() работают, и когда я консолью.регистрируйте возвращаемое значение useRouter(), я получаю полный набор свойств объекта NextJS useRouter:
// >> console.log(useRouter()); inside Storybook
{
route: "/",
pathname: "/",
query: {},
asPath: "/",
events: {},
isFallback: false,
locale: 'en'
}
- Однако в модульном тестировании при регистрации возвращаемого значения
useRouter();
внутри моего компонента оно возвращаетсяnull
. Понятно, что, поскольку оно равно null,{ locale }
присвоение переменной выдает ошибку в моем модульном тестировании. - При регистрации значения
useRouter
переменной как в моем предварительном просмотре сборника рассказов, так и в моем модульном тестировании я получаю следующую функцию:
// >> console.log(useRouter.toString())
function useRouter() {
return _react.default.useContext(_routerContext.RouterContext);
}
У кого-нибудь есть идеи о том, что может пойти не так? Я довольно новичок в Storybook, но я пытался просмотреть проблемы GitHub и онлайн и не смог решить. Понятия не имею, почему useRouter()
возвращает null внутри Jest, если composeStories()
fn должен позаботиться о разрешении моих параметров и аргументов сборника рассказов. Любая информация будет оценена.
Комментарии:
1. можете ли вы проверить, исправляет ли последняя версия storybook-addon-next-router эту проблему для вас? если нет, откройте проблему на GitHub, и я сделаю все возможное, чтобы помочь
Ответ №1:
Я работал с той же проблемой. Я решил это, экспортировав WithNextRouter
в качестве декоратора на preview.js
// preview.js
import { WithNextRouter } from 'storybook-addon-next-router/dist/decorators';
export const decorators = [WithNextRouter];