在NextJS+GraphQL+Apollo+i18n项目配置React Testing Library遇解构错误
解决Next.js+i18n项目中React Testing Library测试时语言内容未加载的问题
你遇到的TypeError: Cannot destructure property 'pageTitle' of '_languageContent.default[locale]' as it is undefined错误,本质是测试环境下组件没拿到正确的locale值,导致语言内容匹配失败。以下是几个可行的解决方法:
1. 正确Mock路由的locale参数
next-router-mock默认不会自动处理locale,需要手动配置路由的locale属性。你可以直接mockuseRouter返回包含正确locale的对象:
import { render, screen } from '@testing-library/react'; import { useRouter } from 'next/router'; import MyPage from '../pages/[locale]/my-page'; // 覆盖next/router的useRouter方法,返回测试所需的locale jest.mock('next/router', () => ({ useRouter: () => ({ locale: 'en-US', pathname: '/[locale]/my-page', query: { locale: 'en-US' } }) })); test('页面渲染正确标题', () => { render(<MyPage />); expect(screen.getByText('预期的页面标题')).toBeInTheDocument(); });
也可以用next-router-mock的实例来设置当前URL和locale:
import { render, screen } from '@testing-library/react'; import { mockRouterInstance } from 'next-router-mock'; import MyPage from '../pages/[locale]/my-page'; beforeEach(() => { // 设置带locale的完整URL mockRouterInstance.setCurrentUrl('/en-US/my-page'); // 或者直接指定locale mockRouterInstance.locale = 'en-US'; }); test('页面渲染正确标题', () => { render(<MyPage />); expect(screen.getByText('预期的页面标题')).toBeInTheDocument(); });
2. Mock语言内容模块
如果路由mock还是不生效,可以直接mock你的_languageContent模块,确保测试时能拿到对应locale的内容:
import { render, screen } from '@testing-library/react'; import MyPage from '../pages/[locale]/my-page'; // 手动指定不同locale对应的语言内容 jest.mock('../path/to/_languageContent', () => ({ default: { 'en-US': { pageTitle: 'English Page Title' }, 'fr-FR': { pageTitle: 'French Page Title' } } })); test('英文页面渲染正确标题', () => { // 这里如果组件依赖路由locale,还是需要配合上面的路由mock render(<MyPage />); expect(screen.getByText('English Page Title')).toBeInTheDocument(); });
3. 适配next-i18next(如果使用该库)
如果项目用的是next-i18next做国际化,测试时需要用I18nextProvider包裹组件,确保i18n上下文正常:
import { render, screen } from '@testing-library/react'; import { I18nextProvider } from 'react-i18next'; import i18n from '../i18n'; // 你的i18n配置文件 import MyPage from '../pages/[locale]/my-page'; test('页面加载正确语言内容', () => { render( <I18nextProvider i18n={i18n}> <MyPage /> </I18nextProvider> ); expect(screen.getByText('预期标题')).toBeInTheDocument(); });
核心思路就是确保测试环境下,组件能获取到正确的locale值,或者直接让语言内容模块返回预设的有效值,避免解构undefined的情况。
内容的提问来源于stack exchange,提问作者Neil Kelsey
相关产品推荐
相关产品推荐

