如何在Node环境用Jest测试非模块化客户端JavaScript库?
非模块化客户端JavaScript库的Jest单元测试方案
问题背景
需要用Node和Jest测试一个非模块化的客户端JavaScript库(无DOM依赖),require('./foo')无法加载该库(非CommonJS模块),不想改造原库,目前只能将代码粘贴到测试文件中,寻求更优方案。
可行解决方案
方案1:通过Jest初始化脚本全局加载库
适合多个测试文件共用该库的场景:
- 创建加载脚本
load-foo.js,读取并执行目标库代码,将全局变量挂载到Node的global对象:
const fs = require('fs'); const path = require('path'); // 读取foo.js内容 const fooContent = fs.readFileSync(path.resolve(__dirname, './foo.js'), 'utf8'); // 执行代码,使std成为全局变量 eval(fooContent); // 显式挂载到global,确保测试文件能访问 global.std = std;
- 在
jest.config.js中配置初始化脚本:
module.exports = { setupFiles: ['./load-foo.js'] };
- 测试文件
foo.test.js无需粘贴代码,直接编写测试:
test('std.nothingP', () => { expect(std.nothingP(null)).toBe(true); expect(std.nothingP(undefined)).toBe(true); expect(std.nothingP(42)).toBe(false); expect(std.nothingP("Hello World")).toBe(false); expect(std.nothingP({})).toBe(false); expect(std.nothingP([])).toBe(false); });
方案2:在测试文件中直接读取并执行库代码
适合单个测试文件使用该库的场景,无需全局配置:
const fs = require('fs'); const path = require('path'); // 读取并执行foo.js,生成全局变量std const fooCode = fs.readFileSync(path.join(__dirname, './foo.js'), 'utf8'); eval(fooCode); test('std.nothingP', () => { expect(std.nothingP(null)).toBe(true); expect(std.nothingP(undefined)).toBe(true); expect(std.nothingP(42)).toBe(false); expect(std.nothingP("Hello World")).toBe(false); expect(std.nothingP({})).toBe(false); expect(std.nothingP([])).toBe(false); });
方案3:自定义Jest转换器,将非模块转为可导入模块
最接近模块化导入的方式,无需污染全局变量:
- 创建转换器
transformers/global-to-module.js,为原库代码添加导出语句:
module.exports = { process(src) { // 假设库暴露的全局变量是std,添加导出逻辑 return `${src}\nmodule.exports = std;`; } };
- 在
jest.config.js中配置转换器:
module.exports = { transform: { '\\.js$': './transformers/global-to-module.js' } };
- 测试文件中直接导入使用:
const std = require('./foo'); test('std.nothingP', () => { expect(std.nothingP(null)).toBe(true); expect(std.nothingP(undefined)).toBe(true); expect(std.nothingP(42)).toBe(false); expect(std.nothingP("Hello World")).toBe(false); expect(std.nothingP({})).toBe(false); expect(std.nothingP([])).toBe(false); });
内容的提问来源于stack exchange,提问作者BitTickler
相关产品推荐
相关产品推荐

