如何对jasmine.createSpyObj创建的间谍对象使用callThrough方法
问题核心原因分析
jasmine.createSpyObj返回的是 包含多个独立间谍方法的普通对象,不存在顶层的and属性,你调用exampleSpy.and.callThrough()本身就会抛出错误:and配置对象仅挂载在每一个单独的间谍方法上,比如exampleSpy.method1.and、exampleSpy.method2.and。- 你传入
createSpyObj第二个参数的对象值,会被Jasmine直接作为对应方法的返回值,而非方法实现。也就是说你写method2: () => 'testResult'时,调用exampleSpy.method2()返回的是这个箭头函数本身,不会执行它得到testResult,所以你的断言必然失败。 callThrough的作用是让间谍调用原始的被间谍化的真实方法,而你通过createSpyObj创建的是纯虚构的间谍对象,没有绑定任何真实实现,直接调用callThrough没有任何可执行的真实逻辑,调用方法会返回undefined。
对应场景解决方案
场景1:仅需要预定义间谍方法返回值,不需要调用真实逻辑
这种场景完全不需要使用 callThrough,正确写法如下:
// 第二个参数直接传你要的返回值即可,不需要包函数 const exampleSpy = jasmine.createSpyObj('ExampleSpy', { method1: Promise.resolve(true), method2: 'testResult' }); const res = exampleSpy.method2(); expect(res).toBe('testResult'); // 断言通过
场景2:需要预定义自定义实现,后续可切回该实现
如果你需要给间谍方法绑定自定义执行逻辑,后续可以反复切换调用这个逻辑,用 and.callFake 绑定即可,效果等价于你预期的 callThrough:
// 第一步:先创建仅声明方法名的间谍对象 const exampleSpy = jasmine.createSpyObj('ExampleSpy', ['method1', 'method2']); // 第二步:预定义每个方法的自定义实现 const customImpls = { method1: () => Promise.resolve(true), method2: () => 'testResult' }; exampleSpy.method1.and.callFake(customImpls.method1); exampleSpy.method2.and.callFake(customImpls.method2); // 临时修改method2的返回值 exampleSpy.method2.and.returnValue('tempResult'); expect(exampleSpy.method2()).toBe('tempResult'); // 切回预定义的自定义实现 exampleSpy.method2.and.callFake(customImpls.method2); expect(exampleSpy.method2()).toBe('testResult'); // 断言通过
场景3:需要间谍真实类实例,可调用原生方法
如果你是要给已有的业务类创建间谍实例,让间谍方法默认可以调用真实逻辑,用 spyOnAllFunctions 实现:
// 真实业务类 class Example { method1() { return Promise.resolve(true); } method2() { return 'testResult'; } } // 创建实例后间谍所有方法,默认就是callThrough状态 const realInstance = new Example(); const exampleSpy = spyOnAllFunctions(realInstance); expect(exampleSpy.method2()).toBe('testResult'); // 临时修改返回值 exampleSpy.method2.and.returnValue('temp'); expect(exampleSpy.method2()).toBe('temp'); // 切回原生方法实现 exampleSpy.method2.and.callThrough(); expect(exampleSpy.method2()).toBe('testResult');
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

