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

测试Observable管道tap内httpCache.put调用失败,求解决方案

测试httpCache.put调用失败的原因分析与解决办法

业务代码

public getTransportAgreement(): Observable<TransportAgreement> {
    const cache: TransportAgreement = this.httpCache.get(
        this.agreementUrl
    ) as unknown as TransportAgreement;
    if (cache) {
        return of(cache);
    }
    return this.http.get(this.agreementUrl).pipe(
        tap((agreement: TransportAgreement) => {
            this.httpCache.put(this.agreementUrl, agreement as any);
        })
    );
}

原测试代码

fit('can get put transport agreement cache', () => {
    spectatorHttp.service.getTransportAgreement().subscribe(() => {
        expect(spectatorHttpCache.service.put).toHaveBeenCalled();
    });
});

失败原因

  1. 缓存命中跳过put逻辑:如果httpCache.get默认返回非空值,方法会直接返回缓存的Observable,完全不会进入HTTP请求分支,tap里的put操作根本不会执行,断言自然失败。
  2. HTTP请求未完成:测试仅订阅了目标方法,但没有mock HTTP请求的响应结果,Observable处于未完成状态,tap内的逻辑不会触发,且测试可能在异步操作结束前就完成了断言。

解决办法

步骤1:强制走HTTP请求分支

在测试开始前mockhttpCache.get返回null,确保代码不会命中缓存:

spyOn(spectatorHttpCache.service, 'get').and.returnValue(null);

步骤2:Mock并触发HTTP响应完成

用Spectator的HTTP测试工具,手动触发请求的响应,让Observable完成,确保tap逻辑执行:

const mockAgreement: TransportAgreement = { /* 填充测试用的协议数据 */ };
spectatorHttp.expectOne(spectatorHttp.service['agreementUrl']).flush(mockAgreement);

步骤3:避免异步测试提前结束

确保测试在异步操作完成后再执行断言,可直接利用Spectator的HTTP工具特性,无需额外的done回调。


修改后的完整测试代码

fit('should call httpCache.put when fetching transport agreement', () => {
    // 1. Mock缓存为空,强制走HTTP请求分支
    spyOn(spectatorHttpCache.service, 'get').and.returnValue(null);
    
    // 2. 订阅目标方法
    spectatorHttp.service.getTransportAgreement().subscribe();
    
    // 3. Mock并触发HTTP响应,触发tap内的put逻辑
    const mockAgreement: TransportAgreement = { id: 'test-id', /* 其他必要字段 */ };
    spectatorHttp.expectOne(spectatorHttp.service['agreementUrl']).flush(mockAgreement);
    
    // 4. 精准断言put的调用参数
    expect(spectatorHttpCache.service.put).toHaveBeenCalledWith(
        spectatorHttp.service['agreementUrl'], 
        mockAgreement
    );
});

内容的提问来源于stack exchange,提问作者Tobias Foxtrot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:01:06