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

使用jasmine-marble为含withLatestFrom的代码编写单元测试报错如何解决

问题修复方案

错误原因拆解

你遇到的报错是由3个核心写法错误导致的:

  1. 断言对象错误:你直接把app.getData方法本身传入了toBeObservable,但该方法需要接收Observable实例作为匹配对象,你需要先调用getData()拿到返回的流再断言。
  2. 预期流结构不符合withLatestFrom的行为:withLatestFrom组合两个Observable后,只会发射单个数组值,数组内按顺序包含两个源Observable的最新值,而不是分两次发射两个独立的布尔值。你写的(cd|)表示同一时间帧发射两个next通知+1个complete通知,和实际流的输出结构不匹配,也是你看到notification.kind匹配失败的直接原因。
  3. 未提前触发依赖Observable的发射:withLatestFrom只会在上游Observable(也就是this.firstObservableClass)发射值时,才组合this.secObservableClass的最新值,如果你没有在测试中提前模拟两个依赖Observable的发射,实际流不会产出你预期的值。

修复后的测试用例写法

首先你需要先模拟两个依赖的Observable,再构造正确的预期流,最后断言:

// 1. 先模拟两个依赖的Observable的发射行为
const first$ = cold('a', { a: true });
const sec$ = cold('b', { b: true });
// 把组件内的两个Observable替换成你模拟的流
app.firstObservableClass = first$;
app.secObservableClass = sec$;

// 2. 构造正确的预期流:withLatestFrom返回的是单个数组值,之后完成
// 这里的(x|)表示同一时间帧发射一个next值、然后立即完成
const expected = cold('(x|)', { x: [true, true] });

// 3. 调用getData拿到返回的Observable,再做断言
expect(app.getData()).toBeObservable(expected);

// 触发冷流的订阅执行
flush();

如果你getData()内部是订阅之后没有把Observable返回出来,那你需要调整组件代码,把pipe之后的Observable作为返回值返回,否则无法直接用toBeObservable断言。

额外注意事项

  • 如果你不需要关心流的完成通知,只需要关心发射的值,可以把预期流写成x,不需要加|,避免匹配不必要的complete事件。
  • 要确保两个依赖的Observable在firstObservableClass发射之前,secObservableClass已经有过发射值,否则withLatestFrom不会触发输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:54:03