You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在服务端mock Next.js客户端动态导入以适配Jest SSR测试

适配Next.js SSR Jest测试的动态导入Mock方案

核心思路

通过手动Mock next/dynamic 模块,根据导入配置的ssr参数做分支处理,同时改造预加载逻辑过滤客户端动态导入,既保留node测试环境的浏览器API校验能力,又符合两类动态导入的快照预期。

实现步骤

1. 创建next/dynamic手动Mock

在项目根目录的__mocks__/next/dynamic.js文件中添加如下代码:

const actualDynamic = jest.requireActual('next/dynamic').default;
// 存储所有服务端动态导入的加载器
const ssrImportLoaders = [];

const mockDynamic = (loader, options = {}) => {
  // 客户端动态导入(ssr显式为false):直接返回空组件,SSR渲染时不输出内容
  if (options.ssr === false) {
    return () => null;
  }
  // 服务端动态导入:加入预加载队列,走原生dynamic逻辑
  ssrImportLoaders.push(loader);
  return actualDynamic(loader, options);
};

// 自定义预加载方法,仅预加载服务端动态导入
export const preloadSsrDynamic = async () => {
  await Promise.all(ssrImportLoaders.map(loader => loader()));
  // 清空队列避免跨用例污染
  ssrImportLoaders.length = 0;
};

export default mockDynamic;

2. 配置Jest识别Mock

在jest.config.js中确认如下配置:

module.exports = {
  testEnvironment: 'node',
  // 确保手动Mock生效
  resetMocks: false,
  // 可选:如果需要全局生效,可在setupFilesAfterEnv中引入Mock
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
};

可以直接卸载jest-next-dynamic依赖,上述方案已经内置了服务端动态导入的预加载能力,避免原库处理ssr:false导入时的报错问题。

3. 调整SSR测试用例

在SSR测试的前置钩子中调用自定义预加载方法即可:

import { preloadSsrDynamic } from '__mocks__/next/dynamic';
import { renderToString } from 'react-dom/server';
import App from '../pages/index';

beforeAll(async () => {
  // 仅预加载服务端动态导入
  await preloadSsrDynamic();
});

test('SSR 渲染快照符合预期', () => {
  const html = renderToString(<App />);
  expect(html).toMatchSnapshot();
});

效果验证

  • 服务端动态导入的组件会正常预加载并渲染,完整出现在SSR快照中
  • 客户端动态导入的组件返回空函数,SSR快照中不会出现对应内容
  • 测试环境保持node,服务端代码如果误引用window等浏览器API会直接抛出错误,符合SSR测试的校验要求

注:此前误以为Jest不支持按入参条件Mock,实际是Mock返回函数即可接收动态导入的配置参数,自由实现分支逻辑。

内容的提问来源于stack exchange,提问作者tunesmith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:15:07