0

Below error shown when I ran ng test command.

Here is my service spec,

describe('BackendService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        {
          provide: Http, useFactory: (backend, options) => {
            return new Http(backend, options);
          },
          deps: [MockBackend, BaseRequestOptions]
        },
        MockBackend,
        BaseRequestOptions,
        BackendService
      ]
    });
  });

  it('should ...', inject([BackendService, MockBackend], (service: BackendService) => {
    expect(service).toBeTruthy();
  })

); });

BackendService.ts looks like,

export class BackendService {
  private baseUrl: string = 'https://foo-backend.appspot.com/_ah/api/default/v1';

  constructor(private http: Http, baseName: string) {
    this.baseUrl = this.baseUrl + baseName;
  }
  .....
}

It seems like extra parameter inside the BackendService class's constructor causes this problem..

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274

1 Answers1

1

How do you expect Angular to know what baseName is supposed to be? All constructor parameters need to be obtained from the Injector. And if there is no corresponding token for the parameter, then it can't be looked up.

You can add a token by doing

// somewhere in some file
import { OpaqueToken } from '@angular/core';

export const BASE_NAME_TOKEN = new OpaqueToken("app.base_name");

// in test class
import { BASE_NAME_TOKEN } from 'where-ever'

TestBed.configureTestingModule({
  providers: [
    BackendService,
    { provide: BASE_NAME_TOKEN, useValue: 'whatever-the-base-is' }
  ]
});

// in service constructor
import { Inject } from '@angular/core'
import { BASE_NAME_TOKEN } from 'where-ever'

constructor(http: Http, @Inject(BASE_NAME_TOKEN) baseName: string) {}

See Also:

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I don't want to change anything in my constructor code. For now, it works totally fine.. But I don't know how to write the testcase.. I have configured the testbed like you did.. – Avinash Raj Jan 02 '17 at 14:25
  • How do you expect Angular to know where to get `baseName` from? There's no magic that's gonna happen. You need to configure the Injector to know how to get it. Otherwise, don't add it as a parameter – Paul Samsotha Jan 02 '17 at 14:28
  • _"But I don't know how to write the testcase"_ What part of the test case do you not know how to write? – Paul Samsotha Jan 02 '17 at 14:31
  • ya, is that we can't pass the constructor's second parameter's value from the testcase? ie, during the BackendService instance creation .. – Avinash Raj Jan 02 '17 at 14:31
  • You could, by instantiating the service yourself, but that doesn't do anything for the application. The test might pass, then your application will fail. This way is a _must_ if you want the extra parameter – Paul Samsotha Jan 02 '17 at 14:33
  • In the application, you will also need to configure the same in the `@NgModule.providers` – Paul Samsotha Jan 02 '17 at 14:34
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/132149/discussion-between-avinash-raj-and-peeskillet). – Avinash Raj Jan 03 '17 at 05:52