web-dev-qa-db-fra.com

Angular 5 services n'ayant pas réussi les tests unitaires avec (NullInjectorError: aucun fournisseur pour HttpClient!)

Je continue à recevoir les erreurs suivantes lors de l'exécution des tests unitaires

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();
      }
    )
  );
});

Je ne comprends pas ce qui ne va pas car j'ai inclus HttpClient dans api.service.ts, le service fonctionne dans le navigateur.

Ceci est appelé directement dans un composant appelé MapComponent, appelé à l'intérieur de 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

Les raisons pour "NullInjectorError: No provider for HttpClient!" sont des dépendances non résolues. Dans ce cas, l’absence de HttpClientModule.

Dans votre fichier .service.spec.ts, ajoutez

  imports: [
        HttpClientTestingModule,
    ],

Vous remarquerez peut-être que j'ai écrit HttpClientTestingModule au lieu de HttpClientModule. La raison en est que nous ne souhaitons pas envoyer de requêtes http réelles, mais plutôt utiliser une API simulée du framework de test.

36
JP07

Essayez d’emballer votre inject dans un async, comme ci-dessous:

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();
  })));

});

N'oubliez pas d'importer async de @angular/core/testing.

J'ai eu un bon succès avec cela. C'est la seule différence entre vos tests unitaires et les miens où j'utilise HttpClientTestingModule.

8
R. Richards

ajoutez-le simplement comme ça,

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