web-dev-qa-db-ja.com

Angular 5サービスがユニットテストに失敗する(NullInjectorError:HttpClientのプロバイダーがありません!)

単体テストの実行中に次のエラーが発生し続けます

Error: StaticInjectorError(DynamicTestModule)[ApiService -> HttpClient]: 
      StaticInjectorError(Platform: core)[ApiService -> HttpClient]: 
        NullInjectorError: No provider for HttpClient!

api.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ApiService {

  constructor(private http: HttpClient) { }
  url = './assets/data.json';

  get() {
    return this.http.get(this.url);
  }
}

api.service.spec.ts

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

import { ApiService } from './api.service';

describe('ApiService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
      ],
      providers: [
        ApiService,
      ],
    });
  });

  it('should get users', inject([HttpTestingController, ApiService],
      (httpMock: HttpTestingController, apiService: ApiService) => {
        expect(apiService).toBeTruthy();
      }
    )
  );
});

HttpClientをapi.service.tsに含めたため、何が問題なのか理解できません。サービスはブラウザーで動作します。

これは、MapComponentというコンポーネントで直接呼び出され、HomeComponent内で呼び出されます。

Chrome 63.0.3239 (Mac OS X 10.13.3) HomeComponent expect opened to be false FAILED
    Error: StaticInjectorError(DynamicTestModule)[ApiService -> HttpClient]: 
      StaticInjectorError(Platform: core)[ApiService -> HttpClient]: 
        NullInjectorError: No provider for HttpClient!
31
user6885115

"NullInjectorError: No provider for HttpClient!"の理由は未解決の依存関係です。この場合、HttpClientModuleがありません。

.service.spec.tsファイルに以下を追加します

  imports: [
        HttpClientTestingModule,
    ],

HttpClientTestingModuleの代わりにHttpClientModuleを書いたことにお気づきかもしれません。その理由は、実際のhttp要求を送信するのではなく、テストフレームワークのMock APIを使用するためです。

36
JP07

以下のように、injectasyncでラップしてみてください。

import { TestBed, async, inject } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { ApiService } from './api.service';

describe('ApiService', () => {
    beforeEach(() => {
      ...
    });    

  it(`should create`, async(inject([HttpTestingController, ApiService],
    (httpClient: HttpTestingController, apiService: ApiService) => {
      expect(apiService).toBeTruthy();
  })));

});

@angular/core/testingからasyncをインポートすることを忘れないでください。

私はこれで大成功を収めました。 HttpClientTestingModuleを使用する単体テストと私の唯一のテストとは異なります。

8
R. Richards

このように追加するだけです

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientModule,
      ],
    }).compileComponents();
  });
3
M.Octavio