在Angular中使用HttpClient依赖关系测试抽象类

时间:2019-08-17 19:34:40

标签: angular unit-testing jasmine abstract-class

我正在尝试测试使用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,但是未定义#gethttpTestingController.expectOne( `${url}/${resource.id}` );都会失败。我怀疑后者会失败,因为我没有将HttpClient正确地注入Base类中。

问题1::抽象类的构造函数的参数顺序重要吗? (即http参数应该排在第一,第二,第三吗?有关系吗?)

问题2:如何以可以使用Base的方式实现HttpTestingController类?

此外,如果您发现任何其他错误,或者我的体系结构已完全失效,请告诉我。

0 个答案:

没有答案