NativeScript - модульное тестирование ошибки HttpInterceptor NSLocationStrategy - PullRequest
0 голосов
/ 24 марта 2020

Я пишу приложение с использованием 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);
    }

}

1 Ответ

1 голос
/ 25 марта 2020

Вы должны загрузить NativeScriptRouterModule как NativeScriptRouterModule.forRoot([]), это похоже на загрузку маршрутизатора в вашем модуле приложения с доступными маршрутами. Поскольку это юнит-тест, вы не пройдете здесь маршруты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...