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

Redux-Observable测试logout epic时ignoreElements相关问题咨询

问题原因解答

1. 为什么expectObservable(output$).toBe('|')不生效,只有toBe('')能通过

你构造的热 Observable 用的弹珠串是'a',仅代表第0帧发出authActions.logout()这个next事件,该 Observable 本身不会触发complete通知。
ignoreElements的逻辑是仅过滤上游传来的所有next通知,不会主动生成complete通知,只有上游触发complete的时候,它才会把complete通知向下传递。你的上游action$从来不会complete,自然output$也永远不会触发complete,所以期望有complete事件的'|'肯定无法通过测试,''代表没有任何事件(next、complete、error)发出,才符合实际表现。

2. 为什么语句2的complete回调永远不会触发

和上一个问题是同一个根因:output$永远不会触发complete通知,所以订阅时传入的complete回调函数永远不会被执行,甚至会导致测试因超时报错。

正确的测试写法

你可以从两种方案里选一种适配你的测试场景:

方案1:给测试用的action$补全complete通知

如果你希望测试完整的生命周期,把弹珠串改成'a|'即可:

const action$ = hot('a|', {
  a: authActions.logout(),
});

修改后上游action$在发出logout事件后会立刻触发complete,此时:

  • expectObservable(output$).toBe('|')可以正常通过
  • complete回调会正常触发,done()也能被正常调用

方案2:直接断言副作用,不需要等待complete

实际生产环境中,epic绑定的store action流是永远不会complete的,更贴近实际运行逻辑的写法是不需要监听complete,直接在scheduler执行完成后断言副作用即可:

describe('Logout Epic', () => {
  test('should remove user from localStorage', () => {
    scheduler.run((helpers) => {
      const { hot, expectObservable } = helpers;
      const action$ = hot('a', {
        a: authActions.logout(),
      });
      const deps = testUtils.mockEpicDependencies();
      const output$ = authEpics.logoutEpic(action$, null, deps);
      
      expectObservable(output$).toBe('');
      // 直接断言副作用即可,不需要等complete
      expect(deps.browser.localStorage.removeItem).toHaveBeenCalledWith('user');
      expect(deps.history.push).toHaveBeenCalledWith(ROUTES.LOGIN);
    });
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:09:00