Mathieu Nls
Mathieu Nls

Reputation: 2365

Angular 2+: Inject real http in Tesbed

I have two services: API and Cfg. API consumes a json API while Cfg provides configurations such as url, api key and so on. API receives an injected instance of Cfg and components receive an injected instance of API.

Here how it looks like:

    import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { TranslateService } from '@ngx-translate/core';
import { EventEmitter } from '@angular/core';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import {
    Validators,
    FormBuilder
} from '@angular/forms';
import { Injectable } from '@angular/core';


@Injectable()
export class CfgService {

    constructor(private baseUrl: string, private assetsUrl: string) { }

    public getAPIUrl(): string {
        return this.baseUrl;
    }

    public getAssetsUrl(): string {
        return this.assetsUrl;
    }
}

@Injectable()
export class APIService {
    constructor(
        public http: Http,
        public config: CfgService) {
    }
}

export function configurationProvider(
    baseUrl: string = "https://xxx.xxx/api/",
    assetsUrl: string = "assets"): CfgService {

    return new CfgService(baseUrl, assetsUrl);
}

@Component({
    template: ''
})
export class MyComponent {

    constructor(
        protected translate: TranslateService,
        private api: APIService,
        private formBuilder: FormBuilder
    ) {

    }
}


describe('bob', () => {
    let comp: MyComponent;
    let fixture: ComponentFixture<MyComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [MyComponent],
            providers: [
                { provide: CfgService, useValue: configurationProvider("http://192.168.0.112:8282/api/") },
                APIService
            ],
            imports: [
                FormsModule,
                HttpModule
            ]
        }).compileComponents().then(() => {
            fixture = TestBed.createComponent(MyComponent);
            comp = fixture.componentInstance;
        });;
    }));

    it('should work', async(() => {

        expect(true).toEqual(true);
    }));

});

Upon execution, it fails with:

 bob
    ✖ should work
PhantomJS 2.1.1 (Linux 0.0.0) bob should work FAILED
        ZoneAwareError@webpack:///~/zone.js/dist/zone.js:923:0 <- config/spec-bundle.js:71103:28
        invokeTask@webpack:///~/zone.js/dist/zone.js:398:0 <- config/spec-bundle.js:70578:36
        onInvokeTask@webpack:///~/zone.js/dist/proxy.js:103:0 <- config/spec-bundle.js:70100:49
        invokeTask@webpack:///~/zone.js/dist/zone.js:397:0 <- config/spec-bundle.js:70577:48
        runTask@webpack:///~/zone.js/dist/zone.js:165:0 <- config/spec-bundle.js:70345:57
        drainMicroTaskQueue@webpack:///~/zone.js/dist/zone.js:593:0 <- config/spec-bundle.js:70773:42
        invoke@webpack:///~/zone.js/dist/zone.js:464:0 <- config/spec-bundle.js:70644:44
        timer@webpack:///~/zone.js/dist/zone.js:1540:0 <- config/spec-bundle.js:71720:34
        resolvePromise@webpack:///~/zone.js/dist/zone.js:712:0 <- config/spec-bundle.js:70892:40
        webpack:///~/zone.js/dist/zone.js:763:0 <- config/spec-bundle.js:70943:31

Any ideas? Thanks.

Upvotes: 0

Views: 57

Answers (1)

yurzui
yurzui

Reputation: 214125

Update:

FormsModule doesn't contain FormBuilder provider. Import ReactiveFormsModule instead


Old version:

Move CfgService above before APIService

@Injectable()
export class CfgService {

  constructor(private baseUrl: string,private assetsUrl: string) {}

  public getAPIUrl(): string {
    return this.baseUrl;
  }

  public getAssetsUrl(): string {
    return this.assetsUrl;
  }
}
@Injectable()
export class APIService {
  constructor(
    public http: Http,
    public config: CfgService) {
  }
}

or use forwardRef like

import { forwardRef } from '@angular/core';

@Injectable()
export class APIService {
  constructor(
    public http: Http, 
    @Inject(forwardRef(() => CfgService) public config: CfgService) {
  }
}

Upvotes: 1

Related Questions