Node环境下Jasmine无法创建函数Spy的问题求助
问题根源与解决方案
核心问题拆解
你遇到的问题有两个关键原因:
- 内部函数引用不匹配:
init调用的是模块内本地定义的clone变量,而非导出的client.clone引用——就算你替换了导出的clone,init依然会调用原始函数,spy 根本不会被触发。 - ES模块属性限制:
import * as client得到的命名空间对象,其属性默认是configurable: false,而 Jasmine 的spyOn需要修改属性描述符来实现拦截逻辑,这直接导致spyOn无法正常创建 spy。
解决方案一:用普通对象封装导出函数(最贴近Angular使用方式)
重构模块结构,把函数放到普通对象里导出,这样对象属性默认是可配置的,spyOn 能正常工作,同时确保 init 调用对象内的 clone:
修改后的 index.js:
let state = null; const templates = { obj: { a:1, b:2} }; export const client = { clone: (obj) => JSON.parse(JSON.stringify(obj)), init: () => state = client.clone(templates.obj) };
修改后的 index.spec.js:
import { client } from '../../index.js'; describe("test", () => { it("should spy on the clone method", () => { spyOn(client, 'clone').and.callThrough(); client.init(); expect(client.clone).toHaveBeenCalled(); }); })
解决方案二:手动替换导出的clone为spy(无需大改模块结构)
先调整模块内的引用关系,让 init 指向导出的 clone 绑定,再手动创建spy替换导出的函数:
修改后的 index.js:
let state = null; const templates = { obj: { a:1, b:2} }; // 先导出clone,让init引用这个实时绑定 export const clone = (obj) => JSON.parse(JSON.stringify(obj)); export const init = () => state = clone(templates.obj);
修改后的 index.spec.js:
import * as client from '../../index.js'; describe("test", () => { it("should spy on the clone method", () => { // 保存原始函数,测试后恢复避免影响其他用例 const originalClone = client.clone; // 创建包含原始逻辑的spy const cloneSpy = jasmine.createSpy('clone').and.callFake(originalClone); // 利用writable: true的特性替换导出的clone client.clone = cloneSpy; client.init(); expect(cloneSpy).toHaveBeenCalled(); // 恢复原始函数 client.clone = originalClone; }); })
内容的提问来源于stack exchange,提问作者Dirk Deshommes
相关产品推荐
相关产品推荐

