在我的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?
首先扩展类将使您难以测试所有内容。考虑注入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中测试不同的内容