angularangular2-di

Unit testing a parent class that uses Injector with Router (and other services)


Suppose I have class Foo which provides dependency injected services to all its derived classes, as such:

export class Foo {
    protected fb : FormBuilder;
    protected router : Router;
    protected otherService : OtherService;
    protected anotherService : AnotherService;

    constructor(injector : Injector) {
        this.fb = injector.get(FormBuilder);
        this.router = injector.get(Router);
        this.otherService = injector.get(OtherService);
        this.anotherService = injector.get(AnotherService);
}

which has classes derived from it as such:

export class Bar extends Foo {

    constructor(injector : Injector){
         super(injector);
    }
}

How can I unit test the parent class correctly, without running into:

Error: Can't resolve all parameters for Foo: (?)

At the minute I have (having tried many, many different things to get it to work, but failing :( )

export function main() {

    describe('Class: Foo', () => {
        beforeEach(async(() => {

            TestBed.configureTestingModule({
                providers: [
                    Foo,
                    Injector,
                    OtherService,
                    AnotherService
                ]
            });
        }));


        it('should compile', inject([Foo, Injector], ( foo: Foo, injector : Injector ) => {
            console.log("INJECTOR", injector);
            expect(foo).toBeTruthy();
        }));

    });
}

I've also tried using ReflectiveInjector.resolveAndCreate as such:

{
    provide : Injector,
    useValue: ReflectiveInjector.resolveAndCreate([FormBuilder, Router, OtherService, AnotherService])
}

But still no dice :( Any ideas?


Solution

  • Seems you need to add @Inject decorator for Injector in Foo constructor

    constructor(@Inject(Injector) injector: Injector) {
    

    and configure TestBed properly. More precisely you have to import RouterModule otherwise you will get another issue with Router:

    TestBed.configureTestingModule({
      imports: [
        RouterModule.forRoot([])
      ],
      providers: [    
        FormBuilder,
        Foo,
        OtherService,
        AnotherService
      ]
    });
    

    You can try it in action in Plunker Example