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 操作员的任何帮助

4

1 回答 1

0

我认为问题在于您不应该首先测试操作员是否像这样被调用。

RxJS 5 和 RxJS 6 中的运算符只是函数,它们只是“制定”链的构造方式。这意味着检查是否tap或被catchError调用并不会告诉您有关它的功能或链是否工作的任何信息(它可能会在任何值上抛出异常并且您将无法对其进行测试)。

由于您使用的是 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);
});

我想你会明白这是做什么的......

于 2018-05-28T15:58:40.397 回答