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

如何在Jest中测试未使用export的非模块类?

问题:非模块JS类无法在Jest中导入测试

我有一个MyClass.js文件,为了在HTML中同步加载它,我移除了export代码——因为带type="module"的<script>标签是异步加载的,这样改解决了应用里按需求使用该类的问题。

但现在没法在Jest测试套件里导入这个类,因为它不再是模块了,不管怎么弄MyClass最终都是undefined,我已经确认文件路径是对的。

已尝试的方法

  • 读取代码用eval()解析,但无效:
    const myClassCode = fs.readFileSync('./js/myClass.js', 'utf-8');
    eval(myClassCode);
    
  • 基础的import或require语句,这俩都要求文件是模块,所以没用。
  • 用沙箱提取代码引入测试:
    const classFileContent = fs.readFileSync(path.resolve(__dirname, '../MyClass.js'), 'utf-8');
    
    // 创建带全局对象的新上下文
    const context = {
      MyClass: undefined,
    };
    vm.createContext(context);
    
    // 在创建的上下文中运行类文件代码
    vm.runInContext(classFileContent, context);
    
    // 从上下文中获取类
    const MyClass= context.MyClass;
    

可行解决方案

方案1:给测试环境单独添加导出(不修改生产逻辑)

在MyClass.js末尾添加一段条件导出代码,仅在Node/测试环境生效:

// MyClass.js原有代码
class MyClass {
  // 类的实现
}

// 仅在Node环境下导出类,不影响浏览器全局变量
if (typeof module !== 'undefined' && module.exports) {
  module.exports = MyClass;
}

这样生产环境中它依然是全局可用的类,Jest里直接用const MyClass = require('./MyClass.js')就能导入,完全不破坏原有应用。

方案2:测试文件中手动挂载全局变量

如果不想改动原文件,可在测试文件里读取并执行代码,将类挂载到Node全局对象:

const fs = require('fs');
const path = require('path');

// 读取并执行文件,让类成为全局变量
eval(fs.readFileSync(path.resolve(__dirname, '../MyClass.js'), 'utf-8'));
// 从全局获取类
const MyClass = global.MyClass;

// 测试示例
test('MyClass实例化正常', () => {
  const instance = new MyClass();
  expect(instance).toBeInstanceOf(MyClass);
});

注意:如果原代码中是直接声明class MyClass,在Node环境执行后会是模块级变量,不会自动到global。这时候需要调整原代码,用globalThis挂载类(兼容浏览器和Node):

// MyClass.js修改为
globalThis.MyClass = class MyClass {
  // 类的实现
};

方案3:用Jest配置预加载文件

在Jest配置文件(jest.config.js)中添加setupFiles,让Jest在所有测试前预加载MyClass.js,这样所有测试文件都能直接使用MyClass:

// jest.config.js
module.exports = {
  setupFiles: ['./js/MyClass.js']
};

同样需要确保MyClass通过globalThis挂载为全局变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:48:35