我正在尝试测试使用HttpClient
的抽象服务类。
为此,我遵循了this thread中的建议,实现了抽象类的最基本实例,并尝试对其进行测试。但是我仍然无法正常工作。
经过几次尝试,我目前正在使用下面形式的代码。
抽象类:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Resource } from './models/resource.model';
import { BaseFunctions } from './interfaces/base-functions.interface';
@Injectable({
providedIn: 'root'
})
export abstract class AbstractService<T extends Resource> implements BaseFunctions {
constructor(
public url: string,
public name = 'abstract',
protected http: HttpClient
) {}
get( id: string ): Observable<T> {
return this.http.get<T>( `${this.url}/${id}` );
}
测试代码:
import { TestBed } from '@angular/core/testing';
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { AbstractService } from './abstract.service';
import { Resource } from './models/resource.model';
describe('AbstractService', () => {
const service_name = 'test',
url = `/${service_name}`;
let service: AbstractService<Resource>,
httpClient: HttpClient,
httpTestingController: HttpTestingController;
let resource: Resource;
// create class to mock AbstractService
@Injectable()
class Base extends AbstractService<Resource> {
constructor(
protected http: HttpClient
) {
super( url, service_name, http );
}
}
let abs_service: Base;
beforeEach(() => {
resource = {
id: 'id'
};
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [
{ provide: AbstractService, useValue: abs_service }
]
});
service = TestBed.get( AbstractService );
httpClient = TestBed.get( HttpClient );
httpTestingController = TestBed.get( HttpTestingController );
} ); // end beforeEach
afterEach( () => {
httpTestingController.verify();
} );
it('should be created', () => {
const service: AbstractService<Resource> = TestBed.get(AbstractService);
expect(service).toBeTruthy();
});
describe( '#get', () => {
it( 'should exist', () => {
expect( service.get ).toBeDefined();
} );
it( `should get ${url}/:id`, () => {
service.get( resource.id )
.subscribe();
const req = httpTestingController.expectOne( `${url}/${resource.id}` );
expect( req.request.method ).toBe( 'GET' );
req.flush( resource );
} );
} ); // end #get
});
此代码编译没有错误,但是由于未定义service
,因此测试失败。在其他版本的代码中,我定义了service
,但是未定义#get
或httpTestingController.expectOne( `${url}/${resource.id}` );
都会失败。我怀疑后者会失败,因为我没有将HttpClient
正确地注入Base
类中。
问题1::抽象类的构造函数的参数顺序重要吗? (即http
参数应该排在第一,第二,第三吗?有关系吗?)
问题2:如何以可以使用Base
的方式实现HttpTestingController
类?
此外,如果您发现任何其他错误,或者我的体系结构已完全失效,请告诉我。