Mocha+Node原生断言如何拦截内部调用验证对象修改正确性
实现方案
你不需要引入任何第三方mock库,两种可行方案如下:
方案1:零侵入验证,利用JS对象引用特性直接断言
根本不需要拦截sendObjSomewhere的调用:JS中对象是按引用传递的,bar方法中对传入obj的修改会直接作用在你外部传入的原对象上,且name属性的替换逻辑在调用sendObjSomewhere之前就执行完成。你只需要在测试中await完bar方法的调用,直接断言原对象的name属性是否符合预期即可。
测试用例示例:
const assert = require('node:assert/strict'); // 引入对应模块的foo函数 const { foo } = require('./your-module-path'); describe('foo.bar', () => { it('正确格式化传入对象的name属性', async () => { const instance = foo(); // 构造测试入参 const testObj = { name: 'abc123' }; // 等待bar执行完成 await instance.bar(testObj); // 直接断言原对象的name符合替换规则:所有\w匹配的字符被替换为空 assert.equal(testObj.name, ''); // 多场景校验:包含非word字符的情况 const testObj2 = { name: 'abc!@#123' }; await instance.bar(testObj2); assert.equal(testObj2.name, '!@#'); }); });
注意:你贴出的核心代码中
catch ()存在语法错误,运行前需要补全错误参数为catch (err),否则代码无法正常执行。
方案2:轻量依赖注入,捕获sendObjSomewhere的入参
sendObjSomewhere是foo函数闭包内的私有变量,外部作用域无权限直接访问,在不修改生产代码、不新增依赖的前提下无法直接拦截该方法的调用。如果你需要明确验证sendObjSomewhere被调用时传入的参数值(比如确认修改后的对象确实被传给了该方法,或担心后续逻辑在调用前再次修改对象),只需要对foo做极小的兼容调整,支持可选注入发送逻辑,默认保持原有行为即可,不会影响现有业务调用方的代码。
调整后的foo实现:
function foo(sendImpl) { /* 原有其他逻辑 */ // 优先使用外部传入的发送实现,不存在则沿用原有逻辑 const sendObjSomewhere = sendImpl || ((param) => {/* 原有匿名函数实现逻辑 */}) return { async bar(obj) { try { obj.name = obj.name.replace(/\w/g, ''); await sendObjSomewhere(obj); } catch (err) { console.error('you messed up'); } } } }
对应的测试用例中,可以传入自定义mock函数捕获入参做断言:
const assert = require('node:assert/strict'); const { foo } = require('./your-module-path'); describe('foo.bar', () => { it('将格式化后的对象传入sendObjSomewhere', async () => { // 存储捕获到的调用参数 let capturedParam = null; // 传入mock发送实现,捕获入参,返回resolved promise适配await逻辑 const mockSend = (param) => { capturedParam = param; return Promise.resolve(); }; const instance = foo(mockSend); const testObj = { name: 'test123' }; await instance.bar(testObj); // 断言调用行为和参数正确性 assert.ok(capturedParam, 'sendObjSomewhere应被正常调用'); assert.equal(capturedParam.name, ''); assert.equal(capturedParam, testObj); }); });
两种方案都完全符合依赖限制:仅使用Mocha 9.1.3和Node 16原生断言模块,不需要引入任何第三方扩展。其中方案1不需要修改任何生产代码,是成本最低的实现方式。
内容的提问来源于stack exchange,提问作者Chubby Cows
相关产品推荐
相关产品推荐

