Node.js单元测试:验证模块内部调用的子模块是否被执行
问题分析与解决方案
首先你的代码里存在几个关键问题:
1. 业务代码的语法错误
mainModule.js 中调用 functionModule 时使用了未定义的变量 argument,会直接导致运行报错,需要替换为传入的合法参数(比如 param1):
// mainModule.js 修正后 const functionModule = require('./functionModule'); module.exports = (param1, param2) => { const somethingNew = functionModule(param1); return { somethingNew }; };
2. 测试代码的核心问题
你试图在 mainModule 上监听 functionModule,但 functionModule 是 mainModule 内部通过 require 引入的私有变量,并非 mainModule 导出对象的属性,所以这个监听根本无法捕获到内部调用。
正确测试方案(使用 Proxyquire + Sinon)
用 proxyquire 替换 mainModule 依赖的 functionModule,同时用 sinon 创建监听函数来验证调用:
// mainModule.test.js const proxyquire = require('proxyquire'); const sinon = require('sinon'); const { expect } = require('chai'); describe('mainModule', () => { it('应该调用 functionModule', () => { // 创建 sinon 监听函数 const functionModuleSpy = sinon.spy(); // 用 proxyquire 加载 mainModule,替换依赖为监听函数 const mainModule = proxyquire('../mainModule.js', { './functionModule': functionModuleSpy }); // 调用 mainModule const testParam = 'test-value'; mainModule(testParam, 'param2'); // 验证监听函数被正确调用 expect(functionModuleSpy.calledOnce).to.be.true; expect(functionModuleSpy.calledWith(testParam)).to.be.true; }); });
另一种方案(使用 Chai Spies + Proxyquire)
如果更习惯用 Chai 的监听工具,也可以这么写:
// mainModule.test.js const proxyquire = require('proxyquire'); const chai = require('chai'); const spies = require('chai-spies'); chai.use(spies); const { expect } = chai; describe('mainModule', () => { it('应该调用 functionModule', () => { // 创建 chai 监听函数 const functionModuleSpy = chai.spy(); // 替换依赖并加载 mainModule const mainModule = proxyquire('../mainModule.js', { './functionModule': functionModuleSpy }); // 调用测试 mainModule('test-param', 'another-param'); // 验证调用情况 expect(functionModuleSpy).to.have.been.called.once; expect(functionModuleSpy).to.have.been.called.with('test-param'); }); });
原测试失效的原因
mainModule导出的是一个函数,而非包含functionModule属性的对象,所以chai.spy.on(mainModule, 'functionModule')是在给函数添加不存在的属性,监听无法关联到内部的functionModule调用。- 测试代码还存在变量名拼写错误:
getModuloSpy应为getModuleSpy,不过这只是次要问题,核心还是监听目标错误。
内容的提问来源于stack exchange,提问作者devmed
相关产品推荐
相关产品推荐

