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

如何用Jest对RxJS Observable进行单元测试?遇超时问题

解决Jest测试Observable超时问题

你的测试超时核心原因是使用了done参数但未手动调用它,Jest会一直等待done()触发才结束测试。另外还有两处代码问题会加重这个情况,以下是具体修复方案:

1. 在subscribe中调用done()并处理错误回调

当测试函数声明了done参数时,必须在异步操作完成(成功/失败)时调用done(),否则Jest会超时。同时要补充错误回调,确保出错时也能结束测试:

describe("Api Well Repository", () => {
  it("should retrieve wells", (done) => {
    const apiWellRepository = new ApiWellRepository(
      new InMemoryWellRepository()
    );

    const observable$: Observable<Well[]> = apiWellRepository.retrieveAll();
    observable$.subscribe({
      next: (wells: Well[]) => {
        expect(wells).toStrictEqual([
          {
            id: "1",
            name: "Angola_0",
          },
        ]);
        done(); // 成功时通知Jest测试结束
      },
      error: (error) => {
        done(error); // 失败时传递错误,Jest会标记测试失败
      }
    });
  });
});

2. 修正catchError的错误用法

你当前的catchError直接抛出错误,会导致错误跳出Observable流,无法被subscribe的错误回调捕获,进而done()不会被调用。正确做法是返回一个错误Observable:

import { throwError } from 'rxjs';

retrieveAll = (): Observable<Well[]> =>
  from(this.wellRepository.retrieveAssets()).pipe(
    map((assets: Asset[]) => this.mapper.mapping(assets)),
    catchError(() => {
      // 返回错误Observable,让subscribe能捕获到错误
      return throwError(() => new Error("Something went wrong"));
    })
  );

3. 更简洁的替代方案:使用firstValueFrom + async/await

放弃done参数,改用RxJS的firstValueFrom将Observable转为Promise,结合Jest的async/await语法,代码更简洁且无需手动管理测试结束:

import { firstValueFrom } from 'rxjs';

describe("Api Well Repository", () => {
  it("should retrieve wells", async () => {
    const apiWellRepository = new ApiWellRepository(
      new InMemoryWellRepository()
    );

    const wells = await firstValueFrom(apiWellRepository.retrieveAll());
    expect(wells).toStrictEqual([
      {
        id: "1",
        name: "Angola_0",
      },
    ]);
  });
});

内容的提问来源于stack exchange,提问作者L. Baptiste

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:06:29