93

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.

6
  • 1
    What is the code of the unit test? It matters. Commented Dec 13, 2018 at 20:22
  • Possible duplicate of Angular 4 Error: No provider for HttpClient Commented Dec 13, 2018 at 20:25
  • @KevinDoyon No, my question is about failing in regard to unit tests, not otherwise. Commented Dec 13, 2018 at 20:33
  • 4
    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 Commented Dec 13, 2018 at 20:39
  • @KevinDoyon You're right, thank you, I just needed to import HttpClientTestingModule. Commented Dec 13, 2018 at 20:44

4 Answers 4

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

    });
Sign up to request clarification or add additional context in comments.

10 Comments

Thanks, I just needed to add HttpClientTestingModule to the imports array in the configureTestingModule method.
Yes, I wanted to just post that but I said let make it full , am happy it helped
This helped but import {HttpClientModule} from '@angular/common/http'; is not necessary since the test class does not actually use it.
Thanks! This worked for me in Angular 9. import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; beforeEach(() => TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [myService] }));
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.
|
3
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]
  }));
});

Comments

3

NOTE FOR ANGULAR 18+

Things have changed and you need to use provideHttpClientTesting() now.

The HttpClientTestingModule has been deprecated.

This should work now:

import { provideHttpClientTesting } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';

... 

TestBed.configureTestingModule({
  providers: [ provideHttpClient(), provideHttpClientTesting() ],
...
}).compileComponents();

1 Comment

If we only use the provideHttpClient() the test will pass, so why we need the provideHttpClientTesting() then?? thank u.
-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 { }

UPDATE:

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; must tbe included for unit testing

OPs question does not follow unit testing guidelines. HttpClientTestingModule must be imported in beforeEach

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

Basically, HttpClientTestingModule is injected in dataService for unit testing purposes that prevents StaticInjectorError

1 Comment

The user asks for unit testing... not using it in a service

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.