由于我将代码更新为新的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运算符的
解决方法
我认为问题在于你不应该首先测试运算符是这样调用的.
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); });
我想你会明白这一点……