58

I am importing and using HttpClient in a service as follows:

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

@Injectable({
    providedIn: 'root',
})
export class MyService {
    constructor(private http: HttpClient) { }

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

However, when I run ng test for my unit tests, and when those tests use the service, I am getting the error:

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

The Angular 6 documentation on HTTP just says to do what I did above.

Alexander Nied
  • 11,309
  • 4
  • 26
  • 41
Kingamere
  • 8,454
  • 21
  • 63
  • 100
  • What is the code of the unit test? It matters. – JB Nizet Dec 13 '18 at 20:22
  • Possible duplicate of [Angular 4 Error: No provider for HttpClient](https://stackoverflow.com/questions/46569404/angular-4-error-no-provider-for-httpclient) – Kevin Doyon Dec 13 '18 at 20:25
  • @KevinDoyon No, my question is about failing in regard to unit tests, not otherwise. – Kingamere Dec 13 '18 at 20:33
  • 3
    And that's exactly what that duplicate is about :) You're likely not importing `HttpClientModule` into your test. Your tests create their own modules. If you don't import `HttpClientModule` (or `HttpClientTestingModule`) there, `HttpClient` won't work because Angular doesn't know about it. It doesn't matter that you added `HttpClientModule` to, say, `AppModule`. It needs to be in `TestBed.configureTestingModule`. Could also import a `SharedModule` if you have one, as long as `HttpClientModule` is in the `exports`.But test will be slower because the `SharedModule` would contain unneeded stuff – Kevin Doyon Dec 13 '18 at 20:39
  • @KevinDoyon You're right, thank you, I just needed to import `HttpClientTestingModule`. – Kingamere Dec 13 '18 at 20:44

3 Answers3

100
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import {HttpClientModule} from '@angular/common/http';
import { myService } from './myservice';


describe('myService', () => {

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

       it('should be created', () => {
        const service: myService = TestBed.get(myService);
        expect(service).toBeTruthy();
       });

       it('should have getData function', () => {
        const service: myService = TestBed.get(myService);
        expect(service.getData).toBeTruthy();
       });

    });
Alexander Nied
  • 11,309
  • 4
  • 26
  • 41
The Dead Man
  • 6,229
  • 22
  • 88
  • 151
  • 13
    Thanks, I just needed to add `HttpClientTestingModule` to the `imports` array in the `configureTestingModule` method. – Kingamere Dec 13 '18 at 20:43
  • Yes, I wanted to just post that but I said let make it full , am happy it helped – The Dead Man Dec 13 '18 at 21:04
  • working for me, I was aspecting to add the module in the main test instead it must be added in the test of the service – Salvatore Pannozzo Capodiferro Apr 29 '19 at 13:06
  • 2
    This helped but import {HttpClientModule} from '@angular/common/http'; is not necessary since the test class does not actually use it. – iowatiger08 Sep 11 '19 at 15:21
  • 1
    Thanks! This worked for me in Angular 9. import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; beforeEach(() => TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [myService] })); – Hassan Raza Jun 07 '20 at 08:03
  • I spent most of my time trying to figure out how to create Jasmine Spy HttpClient object until I found this solution. Thanks. – Tinashe Dec 19 '20 at 14:05
  • 4
    A description of what the solution adds--why it works, would be helpful. Without words, I'm forced to do a visual diff between OP's post and this answer. – bob Apr 09 '21 at 14:36
-1

you should add HttpClient into imports of your module where your component is declared

@NgModule({
  declarations: [
    MyComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule
  ],
  providers: []
})
export class AppModule { }
Derviş Kayımbaşıoğlu
  • 26,360
  • 3
  • 47
  • 64
-1
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { myService } from './myservice';

describe('HeaderService', () => {
  beforeEach(() => TestBed.configureTestingModule({
    imports: [ HttpClientTestingModule ],
    providers: [myService]
  }));
});
sanka sanjeewa
  • 773
  • 8
  • 9