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

NgRx Effect单元测试失败排查:预期值含hasValue:true但实际返回值缺失该字段

解决NgRx Effect单元测试中--?(无值输出)的问题

你的测试失败核心原因是Effect中的withLatestFrom没有获取到预期的store数据流,导致整个流卡在了组合步骤,无法继续执行后续的service调用和action分发。

问题分析

你的Effect里用了withLatestFrom(this.addNewLedgerAccountStore$.select(...))来获取表单数据,这个操作符要求源流(action流)和内部流(store selector流)都至少发出过一次值,才会把两者的值组合起来传递给switchMap。但在你的测试代码中,只mock了service的返回,完全没有处理store selector的流——这就导致withLatestFrom一直等待store的流发出值,整个Effect流无法向下执行,最终输出--?(表示流没有发出预期的有效值)。

解决方案

你需要为addNewLedgerAccountStore$的select方法添加mock,让它返回一个包含mockedLedgerAccountForm的可观察流,确保withLatestFrom能拿到需要的表单数据。

修改后的测试代码示例

describe(`AddNewLedgerRequest$`, () => {
  it(`should dispatch AddNewLedgerAccountSuccess action if service succeeds`, () => {
    const action = new fromActions.AddNewLedgerAccountRequest();
    actions$ = hot('-a', { a: action });

    // 新增:mock store selector的返回流,确保发出表单数据
    addNewLedgerAccountStore$.select(AddNewLedgerAccountSelectors.ledgerAccountFormSelector)
      .mockReturnValue(hot('-c', { c: mockedLedgerAccountForm }));

    const outcome = new fromActions.AddNewLedgerAccountSuccess({ ledgerAccount: mockedLedgerAccount });
    const expected$ = cold('--b', { b: outcome });

    const result$ = cold('-b', { b: mockedLedgerAccount });
    addNewLedgerAccountSpy.mockReturnValue(result$);

    expect(effects.addNewLedgerAccountRequest$).toBeObservable(expected$);
    expect(addNewLedgerAccountSpy).toHaveBeenCalledWith(mockedLedgerAccountForm);
  });
});

额外说明

  1. 时间线匹配:这里我们把store的流设为-c(10ms时发出表单数据),和action流-a的时间点一致,这样withLatestFrom会在10ms时完成组合,然后调用service,service返回的-b会在20ms时发出结果,刚好匹配预期的--b(20ms时发出Success action)。
  2. 验证store调用:如果需要,你还可以添加断言来验证store的select方法是否被正确调用:
    expect(addNewLedgerAccountStore$.select).toHaveBeenCalledWith(AddNewLedgerAccountSelectors.ledgerAccountFormSelector);
    

这样修改后,你的Effect就能正常走完整个流程,发出预期的AddNewLedgerAccountSuccess action,测试就能通过了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:57:30