首页 > 解决方案 > Angular 6 测试 - 参考使用 HttpClient 的帮助程序的服务

问题描述

上周我将我们的应用程序从 Angular 5.8 升级到了 6。我将使用 HttpModule 和 Http 更改为使用 HttpClientModule 和 HttpClient。到目前为止一切顺利,前端似乎按预期工作。只是现在一些服务测试失败了,我正在尝试修复它们。基本上我有两种服务:

  1. 直接使用 HttpClient 的服务。

    客户服务:

    import { HttpClient } from "@angular/common/http";
    import { Injectable } from "@angular/core";
    import { map } from "rxjs/operators";
    import { Observable} from "rxjs";
    
    @Injectable()
    export class CustomService {
        constructor(private readonly http: HttpClient) { }
    
        someMethod(): Observable<boolean> {
            return this.http.get("api/some-url").pipe(
                map(res => <boolean>res) }))
            );
        }
    }
    
  2. 使用 ServiceHelper 的服务,该服务使用 HttpClient。

    客户服务:

    import { HttpHeaders } from "@angular/common/http";
    import { Injectable } from "@angular/core";
    import { Observable } from "rxjs";
    
    import { SomeRequest } from "../Models/SomeRequest";
    import { SomeResult } from "../Models/SomeResult";
    import { ServiceHelper } from "./../Helpers/servicehelper";
    
    @Injectable()
    export class CustomService {
        constructor(readonly serviceHelper: ServiceHelper) { }
    
        someMethod(): Observable<SomeResult> {
            const request = {} as SomeRequest;
            const headers = new HttpHeaders({ "Content-Type": "application/json" });
            const options = { headers: headers };
    
            return this.serviceHelper
                .post<SomeRequest, SomeResult>("api/some-url", request, options);
        }
    }
    

    服务助手:

    import { HttpClient } from "@angular/common/http";
    import { Injectable } from "@angular/core";
    import { map } from "rxjs/operators";
    import { Observable } from "rxjs";
    
    import { Result } from "../Models/Result";
    
    @Injectable()
    export class ServiceHelper {
        constructor(readonly http: HttpClient) { }
    
        post<Req, Res extends Result>(url: string, request: Req, options): Observable<Res> {
            return this.http.post(url, request, options).pipe(
                map(data => (data as any) as Res)
            );
        }
    }
    

通过执行以下操作,第一个服务的测试已经重新开始工作:

import { TestBed } from "@angular/core/testing";
import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing";
import { HttpResponse } from "@angular/common/http";

import { CustomService } from "./custom.service";

describe("service tests", () => {
    let service: CustomService;
    let httpClient: HttpTestingController;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [CustomService]
        });
        service = TestBed.get(CustomService);
        httpClient = TestBed.get(HttpTestingController);
    });

    it("should pass", () => {
        service.someMethod().subscribe(result => {
            expect(result).toBe(true);
        });

        httpClient.expectOne("api/some-url").event(
            new HttpResponse<boolean>({ body: true }));
    });
});

对于第二个服务(使用 ServiceHelper),我想在 beforeEach 语句中执行上述操作。我在 configureTestingModule 中尝试了几件事,添加了提供程序和/或导入,但大多数情况下我在运行测试后得到了 StaticInjectorError。

我可以为第二种服务编写测试吗?希望有人可以进一步帮助我!

标签: angularkarma-jasmineangular6angular-httpclient

解决方案


通过将 { provide: ServiceHelper, useClass: ServiceHelper } 添加到提供程序数组来修复它。固定的 configureTestingModule 看起来像:

TestBed.configureTestingModule({
        imports: [HttpClientTestingModule],
        providers: [
            CustomService,
            { provide: ServiceHelper, useClass: ServiceHelper }
        ]
    })

推荐阅读