angulartypescripttesting

NullInjectorError: No provider for HttpTestingController! during angular test


I got this error when I try to test my service I did everything like in this tutorial

          NullInjectorError: No provider for HttpTestingController!
        error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'HttpTestingController', 'HttpTestingController' ] })
            at <Jasmine>
            at NullInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:1076:1)
            at R3Injector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:16629:1)
            at R3Injector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:16629:1)
            at NgModuleRef$1.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:36024:1)
            at TestBedRender3.inject (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:3111:53)
            at Function.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:3005:1)
            at UserContext.beforeEach (http://localhost:9876/_karma_webpack_/src/app/services/weatherService/weather.service.spec.ts:18:24)
            at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:364:1)
            at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist

weatherDto

export class WeatherDto {
    name: String;
    weather: String;
    weatherIcon: String;
    temp: Number;
    pressure: Number;
    minTemp: Number;
    maxTemp: Number;
}

weather service

import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { WeatherDto } from 'src/app/models/weather-dto.model';


@Injectable({
  providedIn: 'root'
})
export class WeatherService {
  requestUrl = environment.baseUrl + environment.weatherUrl;
  token = environment.token;

  constructor(private http: HttpClient) { }

  getWeather(): Observable<WeatherDto> {
    var header = {
      headers: new HttpHeaders()
        .set('Authorization', `Bearer ${this.token}`)
        .set('Content-Type', 'application/json')

    }
    return this.http.get<WeatherDto>(this.requestUrl, header);
  }
}

test

import { TestBed } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import { HttpTestingController } from '@angular/common/http/testing';

import { WeatherService } from './weather.service';
import { WeatherDto } from 'src/app/models/weather-dto.model';

describe('WeatherService', () => {
  let service: WeatherService;
  let httpMock: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientModule],
      providers: [WeatherService]
    }).compileComponents();
    service = TestBed.inject(WeatherService);
    httpMock = TestBed.get(HttpTestingController);
  });

  it('be able to retrieve weather from the API via GET', () => {
    const dummyWeather: WeatherDto = {
      name: 'City',
      weather: 'Clear',
      weatherIcon: '02d',
      temp: 20.0,
      pressure: 1024.0,
      minTemp: 18.0,
      maxTemp: 22.0
    };
    service.getWeather().subscribe(data => {
      expect(data.name).toEqual('City');

    });

    const request = httpMock.expectOne(`http://localhost:8080/api/weather`);
    expect(request.request.method).toBe('GET');
    request.flush(dummyWeather);

    afterEach(() => {
      httpMock.verify();
    });
  });
})

So I do hit to my spring boot api and I get good response. But when I tried to test this service I can not how to do it. What is weired for me I got also Chrome 71.0.3578 (Linux 0.0.0) WeatherComponent should create FAILED but I deleted part responsible for this part of test. I'm out of ideas what I am doing wrong?!


Solution

  • You should have it like this instead:

      HttpClientTestingModule,
      HttpTestingController,
    } from '@angular/common/http/testing';
    
    
    beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [HttpClientTestingModule],
          providers: [WeatherService]
        }).compileComponents();
        service = TestBed.inject(WeatherService);
        httpMock = TestBed.get(HttpTestingController);
      });