NativeScript-单元测试HttpInterceptor NSLocationStrategy错误



我正在用NativeScript 6.4.1和Angular 8编写一个应用程序。

我想为我的HttpInterceptor编写单元测试。我的拦截器添加了一个令牌来选择http调用,并在用户从后端收到某些错误时将其路由到身份验证页面。

代码运行良好,可以工作,但我的单元测试没有。

当我运行单元测试时,我会得到以下错误:

NullInjectorError: StaticInjectorError(DynamicTestModule)[RouterExtensions -> NSLocationStrategy]:
StaticInjectorError(Platform: core)[RouterExtensions -> NSLocationStrategy]:
NullInjectorError: No provider for NSLocationStrategy!
error properties: Object({ originalStack: 'Error: NullInjectorError: No provider for NSLocationStrategy!
at new ZoneAwareError (file:///data/data/org.nativescript.SelfServiceApp/files/app/vendor.js:157861:33)

我不知道为什么我会出错。

这是我的单元测试:

import { nsTestBedBeforeEach } from 'nativescript-angular/testing';
import { TestBed } from '@angular/core/testing';
import { HttpInterceptorService } from '~/app/core/interceptors/http-interceptor-service';
import { HttpLoaderService } from '~/app/core/shared/http-loader.service';
import { AuthenticationService } from '~/app/authentication/shared/services/authentication.service';
import { SsoAuthenticationService } from '~/app/authentication/pages/single-sign-on/sso-authentication.service';
import { EndpointHelperService } from '~/app/core/shared/endpoint-helper.service';
import { RouterExtensions } from 'nativescript-angular/router';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { NativeScriptRouterModule } from 'nativescript-angular/router';
import { Routes, RouterModule } from '@angular/router';
import { CommonModule, Location } from '@angular/common';
describe('HttpInterceptorService Test', () => {
let service: HttpInterceptorService;
beforeEach(nsTestBedBeforeEach([], [
HttpInterceptorService,
HttpLoaderService,
AuthenticationService,
SsoAuthenticationService,
EndpointHelperService,
RouterExtensions
], [
HttpClientTestingModule, 
RouterTestingModule, 
NativeScriptRouterModule, 
CommonModule
]));
it('should be defined', () => {
service = TestBed.get(HttpInterceptorService);
expect(service).toBeTruthy();
});
});

这是我的拦截器:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError, from } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { HttpLoaderService } from '../shared/http-loader.service';
import { boundMethod } from 'autobind-decorator';
import { AuthenticationService } from '../../authentication/shared/services/authentication.service';
import { SsoAuthenticationService } from '../../authentication/pages/single-sign-on/sso-authentication.service';
import { EndpointHelperService } from '../shared/endpoint-helper.service';
import { switchMap } from 'rxjs/operators';
import { RouterExtensions } from 'nativescript-angular/router';
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
constructor(
private httpLoaderService: HttpLoaderService,
private authentication: AuthenticationService,
private ssoAuthentication: SsoAuthenticationService,
private endpointHelper: EndpointHelperService,
private router: RouterExtensions
) {}
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.httpLoaderService.onRequestStart();
// do not add to token endpoints
if (this.endpointHelper.isTokenEndpoint(request.url)) {
return this.returnRequest(request, next);
}
//do not add to registration server
if (this.endpointHelper.isRegisterEndpoint(request.url)) {
return this.returnRequest(request, next);
}
return this.appendSSOTokenToHeader(request, next);
}
@boundMethod
private appendSSOTokenToHeader(request: HttpRequest<any>, next: HttpHandler) {
return from(this.ssoAuthentication.getHttpHeader())
.pipe(
switchMap((newHeader) => {
request = request.clone({ 
body: { ...request.body, clientcode: this.authentication.clientcode },
setHeaders: { Authorization: newHeader },
url: this.authentication.mobileApiUrl + request.url
});
return this.returnRequest(request, next);
})
);
}
@boundMethod
private returnRequest(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(request)
.pipe(tap(this.handleSuccess), catchError(this.handleError));
}
@boundMethod
private handleSuccess(event: HttpEvent<any>): void {
if (event instanceof HttpResponse) {
this.httpLoaderService.onRequestEnd();
}
}
@boundMethod
private handleError(error: HttpErrorResponse) {
this.httpLoaderService.onRequestEnd();
if (this.endpointHelper.shouldRedirectToSSOPage(error)) {
this.router.navigate(['register-via-sso']);
}
return throwError(error);
}
}

您必须将NativeScriptRouterModule加载为NativeScriptRouterModule.forRoot([]),这类似于在具有可用路由的应用程序模块中加载路由器。由于这是单元测试,您不会通过这里的路由。

最新更新