You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:12:02