如何在Angular / Jasmine测试中将HttpClient伪造为私有字段?

问题描述 投票:0回答:1

在我的Angular 9项目中,我有这段代码来定义HttpClient中的DataService。 DataService是应用程序中最常见的服务,其他所有服务都对其进行了扩展。超过50种服务。由于扩展了DataService的大量服务,这就是使用这种方式定义HttpClinet的原因。

如果将创建的HttpClient放入constructor(),则需要在所有50个服务中创建一个新的HttpClient,并且我想避免这种情况。

private是因为我想避免在子服务中直接使用HttpClient。

data.service.ts

import { InjectorInstance } from 'src/app/app.module';

export class DataService<T> {
  private http: HttpClient;

  constructor(model: T) {
    super(model);

    this.http = InjectorInstance.get<HttpClient>(HttpClient);
  }

  // ...
}

app.module.ts

import { Injector, NgModule } from '@angular/core';

export let InjectorInstance: Injector;

@NgModule({
  // ...
})
export class AppModule {
  constructor(private injector: Injector) {
    InjectorInstance = this.injector;
  }
}

现在,我需要在此服务上创建测试,现在需要创建一个伪造的HttpClient。

我想做这样的事情:

describe('DataService', () => {
  let httpClientSpy: { get: jasmine.Spy };
  let service: DataService<any>;
  const model: any = {};

  beforeEach(() => {
    httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
    service = new DataService(model);
    service.http = httpClientSpy;
  });
});

但是这里我出现Property 'http' is private and only accessible within class 'DataService<T>'错误。

如何为该服务创建伪造的HttpClient?

angular unit-testing jasmine automated-tests karma-jasmine
1个回答
0
投票

首先扩展类将使您难以测试所有内容。考虑注入DataService而不是对其进行扩展。然后您可以像这样测试它:

import { TestBed, inject, fakeAsync, tick } from '@angular/core/testing';
import {
  HttpClientTestingModule,
  HttpTestingController,
} from '@angular/common/http/testing';

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [
      HttpClientTestingModule, // angular testing module that provides mocking for http connections
    ],
  });
})

it('should request data from server', fakeAsync(inject([
  HttpClient,
  HttpTestingController,
], (
  httpClient: HttpClient, // this part probably will be used somwhere in tested service or coponent
  httpMock: HttpTestingController, // this part will help us in testing
) => {
  // Arrange
  let result: any = 'no one expects spanish inquisition';
  const path = '{apiEndpoint}/home';
  const data = { some: 'data' };
  const expected = { ...data, wasProcessed: true };

  // Act
  httpClient.get(path)
    // something may modify returned server result
    .pipe(map((data) => Object.assign(data, { wasProcessed: true })))
    // but we just care about what we get in the end
    .subscribe((data) => result = data)

  // Assert
  httpMock.expectOne(path).flush(data);
  tick();

  expect(result).toEqual(expected); // after processing server response
  // check if there arent any other not handled requests
  httpMock.verify();
})));

您可以找到更多示例如何在角度here中测试不同的内容

© www.soinside.com 2019 - 2024. All rights reserved.