Angular 6单元测试rxjs 6操作符tap单元测试拦截器

7

自从我将我的代码更新到新的Rxjs 6之后,我不得不像这样改变拦截器代码:

auth.interceptor.ts:

...
return next.handle(req).pipe(
      tap((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          // do stuff with response if you want
        }
      }),
      catchError((error: any) => {
        if (error instanceof HttpErrorResponse) {
          if (error.status === 401) {
            this.authService.loginRedirect();
          }
          return observableThrowError(this.handleError(error));
        }
      })
    );

我无法测试rxjs操作符"tap"和"catchError"。

实际上,我只能测试管道是否被调用:

it('should intercept and handle request', () => {
    const req: any = {
      clone: jasmine.createSpy('clone')
    };

    const next: any = {
      handle: () => next,
      pipe: () => next
    };

    spyOn(next, 'handle').and.callThrough();
    spyOn(next, 'pipe').and.callThrough();

    interceptor.intercept(req, next);

    expect(next.handle).toHaveBeenCalled();
    expect(next.pipe).toHaveBeenCalled();
    expect(req.clone).toHaveBeenCalled();
  });

如何监控rxjs操作符,任何帮助都将不胜感激。

1个回答

0

我认为问题在于你不应该首先测试操作符是否被调用。

RxJS 5和RxJS 6中的操作符只是“制作配方”构建链的函数。这意味着检查tapcatchError是否被调用并不能告诉你它的功能或者链是否工作(它可能会在任何值上抛出异常,你将无法测试它)。

由于你正在使用RxJS 6,你应该通过发送值来测试链。这在文档中有很好的说明,并且非常容易实现 https://github.com/ReactiveX/rxjs/blob/master/doc/marble-testing.md

在你的情况下,你可以像这样做:

const testScheduler = new TestScheduler((actual, expected) => {
  // some how assert the two objects are equal
  // e.g. with chai `expect(actual).deep.equal(expected)`
});

// This test will actually run *synchronously*
testScheduler.run(({ cold }) => {
  const next = {
    handle: () => cold('-a-b-c--------|'),
  };
  const output = interceptor.intercept(null, next);

  const expected = '   ----------c---|'; // or whatever your interceptor does
  expectObservable(output).toBe(expected);
});

我想你会明白这个做什么...


谢谢你的提示,事实上,这种类型的测试是最简单的,我得到了那些测试401重定向的。也许现在这个测试没有意义。我会查看你的链接,更好地理解这种方法。再次非常感谢。 - Pedro Tainha
它对我实际上并没有起作用,我也有类似的测试用例。无论是使用catchError还是tap,它都没有被调用,我尝试了使用'#'和'|'值的热和冷模式。我遵循了给定的文档。 - ayyappa maddi
@ayyappamaddi 如果你不展示你的代码,没有人能够帮助你。 - martin
大理石测试链接已经失效 - 这是相应的Angular页面 - https://rxjs-dev.firebaseapp.com/guide/testing/internal-marble-tests - plantbeard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接