5

我正在开发一个 Angular 10 应用程序,该应用程序使用HttpInterceptor向所有响应添加特定标头。不幸的是,在尝试测试此拦截器时,我不断收到以下错误:

Error: Expected one matching request for criteria "Match by function: ", found none.

或类似的变体:

Error: Expected one matching request for criteria "Match URL: /endpoint", found none.

我的期望是这个测试会通过,但我现在不知道为什么它不工作。

这是我的拦截器:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
    constructor(private kc: KeycloakService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return Observable.fromPromise(this.kc.getToken()).mergeMap(auth => {
            if (auth) {
                req = req.clone({
                    setHeaders: {
                        Token: auth
                    }
                });
            }

            return next.handle(req);
        })
    }
}

这是我的测试:

// imports removed for clarity

describe('Interceptor', () => {
    let http: HttpClient;
    let httpController: HttpTestingController;
    let mockKeycloakService: KeycloakService;
    let interceptor: AuthInterceptor;

    const TEST_TOKEN = 'test-token';

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [
                KeycloakService,
                {
                    provide: HTTP_INTERCEPTORS,
                    useClass: AuthInterceptor,
                    multi: true
                }
            ],
        });

        http = TestBed.inject(HttpClient);
        httpController = TestBed.inject(HttpTestingController);
        mockKeycloakService = TestBed.inject(KeycloakService);

        spyOn(mockKeycloakService, 'getToken').and.returnValue(new Promise<string>(() => TEST_TOKEN));

        interceptor = new AuthInterceptor(mockService);
    });

    // removed for clarity

    it('adds token to all responses', done => {
        let endpoint = '/endpoint';
        http.get<HttpResponse<any>>(endpoint).subscribe(res => {
            expect(res).toBeTruthy();
            expect(res.headers).toBeTruthy();
            expect(res.headers.get('Token')).toBe(TEST_TOKEN);
        });
        let req = httpController.expectOne(endpoint);

        // The first error occurred when I tried this:
        // let req = httpController.expectOne(res => res.headers.has('Token') && res.headers.get('Token') === TEST_TOKEN);

        let body = { test: 'test-value' };
        console.log(`The URL is: ${req.request.url}`);
        expect(req.request.body).toEqual(body);

        req.flush(body);
        httpController.verify();
    });

    // removed for clarity
});

也就是说,可能值得指出的是,我尝试应用以下资源中的解决方案无济于事(大多数似乎与我已经拥有的类似,而且许多似乎适用于旧版本的 Angular):

  • 来自 Angular 4 的单元测试 HttpInterceptor:在这里,我发现了一篇有用的文章,它几乎完全符合我的需要,但它实际上不适用于我的情况(我遇到了上述错误)。我说的几乎完全是因为我用来获取令牌的服务实际上并没有HttpClient根据我的判断来使用。
  • 与我的问题不完全一样,但足够相似,可以尝试一下。我尝试使用教科书描述的解决方法,但显然这与我遇到的问题还不够接近。
  • 我还尝试在我的测试中使用导致上述错误被消除spyOn的函数,http.get(...)但是当我这样做时它没有调用我的intercept函数。

非常感谢任何帮助 - 谢谢!

4

0 回答 0