Search code examples
angulartestingkarma-jasmineangular8angular-test

Angular 8 karma test a service without injecting all service in the constructor


I'm new to Angular testing with Karma and I'm not understanding how to properly test a service. Let's say I have this service that I have to test:

    @Injectable()
    export class MyService {
        constructor(private httpService: HttpService) { }

        //methods to test
    }

and this is my test class:

    describe('MyService', () => {
      let service: MyService;
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          providers: [MyService],
        }).compileComponents();
        service = TestBed.get(MyService);
      }));
    });

When I run ng test it gives the error NullInjectorError: No provider for HttpService!.
So I add HttpService into providers array in test class, this way:

    describe('MyService', () => {
      let service: MyService;
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          providers: [MyService, HttpService],
        }).compileComponents();
        service = TestBed.get(MyService);
      }));
    });

HttpService is this:

    @Injectable()
    export class HttpService{
        constructor(private httpService: HttpClient) { }
    }

So now I get the error NullInjectorError: No provider for HttpClient!. (HttpClient is from @angular/common/http).
If I add HttpClient to providers array in test class then I get the same error for all the services/class inside HttpClient constructor, and so on. What is the correct way to instatiate a service, without having to add each providers, leading to potential infinite providers?


Solution

  • In your Testbed configuration, import HttpClientTestingModule

      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports: [HttpClientTestingModule],
          providers: [MyService, HttpService],
        }).compileComponents();
        service = TestBed.get(MyService);
      }));
    

    You may consider also

    1. changing TestBed.get(MyService); to TestBed.inject(MyService); as TestBed.get(...) is deprecated What's the difference between TestBed.get and new Service(...dependencies)

    2. changing async to waitForAsync as async is deprecated When to use waitForAsync in angular