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

如何在不重构的情况下对含硬编码依赖的原生JS进行单元测试?

遗留原生JS应用的Jest单元测试问题

我有一个遗留原生JS应用,代码示例如下:

var thing = new Thing();
function do_thing() {
  // Logic to test here
}
// export module

该文件包含许多需单元测试的重要计算逻辑,但我不想对整个应用重构。

我尝试用Jest测试,代码如下:

/**
 * @jest-environment jsdom
 */
const mod = require('thing.js');

test('Test', () => {
  mod.do_thing();
});

但运行报错:

ReferenceError: Thing is not defined

即使移除var thing,若do_thing调用其他文件的函数(遗留项目常见情况),仍会报错:

ReferenceError: foo() is not defined

请问有何解决建议?能否用jest.fn或jest.mock等方法,无需大量重构即可模拟依赖?


解决建议

不用大规模重构,完全可以通过Jest的全局模拟能力处理这些依赖问题,具体方案如下:

1. 模拟全局Thing构造函数

遗留代码直接使用了全局的Thing,可以在测试文件里提前把它挂载到window(jsdom环境的全局对象)上,用jest.fn()模拟:

/**
 * @jest-environment jsdom
 */
// 模拟全局的Thing构造函数,可按需定义实例属性/方法
window.Thing = jest.fn().mockImplementation(() => {
  return { /* 比如: getValue: jest.fn().mockReturnValue(100) */ };
});

const mod = require('./thing.js');

test('Test do_thing', () => {
  mod.do_thing();
  // 还能验证Thing是否被实例化
  expect(window.Thing).toHaveBeenCalled();
});

2. 模拟其他全局函数(如foo())

如果do_thing调用了其他文件的全局函数foo,同样挂载到全局并模拟:

/**
 * @jest-environment jsdom
 */
window.Thing = jest.fn();
// 模拟全局foo函数,自定义返回值或逻辑
window.foo = jest.fn().mockReturnValue('模拟计算结果');

const mod = require('./thing.js');

test('Test do_thing uses foo', () => {
  mod.do_thing();
  expect(window.foo).toHaveBeenCalled();
});

3. 清理全局模拟,避免测试污染

如果担心全局模拟影响其他测试,用Jest的beforeEach和afterEach做前后置处理:

/**
 * @jest-environment jsdom
 */
let originalThing;
let originalFoo;

beforeEach(() => {
  // 保存原全局对象
  originalThing = window.Thing;
  originalFoo = window.foo;
  // 挂载模拟
  window.Thing = jest.fn();
  window.foo = jest.fn();
});

afterEach(() => {
  // 恢复原全局对象
  window.Thing = originalThing;
  window.foo = originalFoo;
});

const mod = require('./thing.js');

test('Test do_thing', () => {
  mod.do_thing();
  expect(window.Thing).toHaveBeenCalled();
});

4. 针对简单导出的模块模拟

如果遗留文件最后有基础导出(比如module.exports = { do_thing }),也可以用jest.mock间接模拟依赖,但全局模拟更适配完全无模块化的原生JS代码。

内容的提问来源于stack exchange,提问作者Olle Härstedt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:33:19