3

I'm new to Angular and I'm missing something when it comes to understanding how DI works. I'm currently trying to get a unit test to pass.

Here is the code for the test;

import { TestBed } from '@angular/core/testing';
import { HttpClientModule, HttpClient } from '@angular/common/http'
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { InjectionToken } from '@angular/core';
import { UserService } from './user.service';

export const BASE_URL = new InjectionToken<string>('BASE_URL');

describe('UserService', () => {
  beforeEach(() => TestBed.configureTestingModule({
    imports: [
      HttpClientTestingModule,
    ],
    providers: [
      { provide: BASE_URL, useValue: 'http://localhost' },
      UserService,
      HttpClient
    ]
  }));

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

Here is the code under test;

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

import { User } from '@/_models';

@Injectable({ providedIn: 'root' })
export class UserService {

  private baseUrl: string

  constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this.baseUrl = baseUrl
  }

  getAll() {
    return this.http.get<User[]>(`${this.baseUrl}/users`);
  }

  getById(id: number) {
    return this.http.get(`${this.baseUrl}/users/${id}`);
  }

  register(user: User) {
    return this.http.post(`${this.baseUrl}/users/register`, user);
  }

  update(user: User) {
    return this.http.put(`${this.baseUrl}/users/${user.id}`, user);
  }

  delete(id: number) {
    return this.http.delete(`${this.baseUrl}/users/${id}`);
  }
}

This is my error;

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

Why am I getting this error and what do I need to do to rectify it?

1
  • 1
    You need to use the injection token or the string value, consistently - the point of the tokens is to disambiguate the same string used in different contexts. Also you don't need to include HttpClient separately from the HttpClientTestingModule. Commented Mar 20, 2019 at 13:33

1 Answer 1

3

Replace { provide: BASE_URL, useValue: 'http://localhost' } with { provide: 'BASE_URL', useValue: 'http://localhost'}

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.