如何对 Next.js 动态组件进行单元测试?

Posted

技术标签:

【中文标题】如何对 Next.js 动态组件进行单元测试?【英文标题】:How to unit test Next.js dynamic components? 【发布时间】:2018-04-05 00:57:23 【问题描述】:

Next.js dynamic() HOC 组件并不是很容易测试。我现在有 2 个问题;

第一个笑话是无法正确编译动态导入(require.resolveWeak is not a function - 似乎是由下一个 babel 插件添加的) 其次,我无法很好地覆盖modules 逻辑;看起来它在尝试渲染动态组件时根本没有运行。

【问题讨论】:

运气好吗? @Simon Boudrias 我也对此感兴趣。似乎唯一的方法是从 jest 中公开一个模拟的 require.resolveWeak ,或者拥有一个不会使用下一个 js 使用的 handler-imports 插件逻辑的自定义 babel 插件。有关将导入更改为 requrie.resolveWeak 的插件,请参见 github.com/zeit/next.js/blob/… 继续模拟下一个/动态...jest.mock('next/dynamic', () => () => 'Dynamic') 你能添加一个模拟动态导入的例子吗?我必须对此进行测试: const DynamicDrawer = dynamic( loader: () => import('./SimpleDrawer/index'), loading: () => null, );但我收到此错误:警告: 使用了不正确的大小写。对 React 组件使用 PascalCase,对 html 元素使用小写。%s 【参考方案1】:

假设我们有一个这样的组件(使用动态导入):

import dynamic from 'next/dynamic';

const ReactSelectNos-s-r = dynamic(() => import('../components/select'), 
    loading: () => <Input />,
    s-s-r: false
);

export default () => (
    <>
        <Header />
        <ReactSelectNos-s-r />
        <Footer />
    </>
);

Next.js 提供的动态导入支持没有公开一种在 Jest 环境中预加载动态导入组件的方法。 但是,感谢jest-next-dynamic,我们可以渲染完整的组件树而不是加载占位符。

您需要像这样将babel-plugin-dynamic-import-node 添加到您的.babelrc


  "plugins": ["babel-plugin-dynamic-import-node"]

然后,您可以使用preloadAll() 来渲染组件,而不是加载占位符。

import preloadAll from 'jest-next-dynamic';
import ReactSelect from './select';

beforeAll(async () => 
    await preloadAll();
);

?Source

【讨论】:

【参考方案2】:

您可以将以下内容添加到您的 Jest 设置前:setupTests.ts

jest.mock('next/dynamic', () => () => 
    const DynamicComponent = () => null;
    DynamicComponent.displayName = 'LoadableComponent';
    DynamicComponent.preload = jest.fn();
    return DynamicComponent;
);

【讨论】:

【参考方案3】:

虽然是一个 hacky 解决方案,但我所做的只是通过提取导入路径并返回该导入来简单地模拟 next/dynamic

jest.mock('next/dynamic', () => (
  __esModule: true,
  default: (...props) => 
    const matchedPath = /(.)*(\'(.*)\')(.)*/.exec(props[0].toString());
    if (matchedPath) return require(matchedPath[3]);
    else return () => <></>;
  ,
));

【讨论】:

这将如何工作?您正在将匿名函数传递给 next/dynamic,因此您无法从中提取路径【参考方案4】:

如果您遇到 Next8 的第一个问题,您可以使用以下命令模拟动态导入:

jest.mock('next-server/dynamic', () => () => 'Dynamic');

参考见:

https://spectrum.chat/next-js/general/with-jest-and-dynamic-imports-broken~25905aad-901e-41d8-ab3e-9f97eeb51610?m=MTU1MzA5MTU2NjI0Nw==

https://github.com/zeit/next.js/issues/6187#issuecomment-467134205

【讨论】:

以上是关于如何对 Next.js 动态组件进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何对 Joomla 2.5 组件进行单元测试

如何对第一个Vue.js组件进行单元测试 (上)

如何对依赖于 ActivatedRoute 参数的组件进行单元测试?

如何对以 TemplateRef 作为输入的 Angular 组件进行单元测试?

如何对自定义 Wicket 组件进行单元测试

如何对 React-Redux 连接组件进行单元测试?