2016-11-04 2 views
6

Ich erstelle Komponenten dynamisch mit ComponentFactoryResolver und übergebe sie dynamisch mit dem ReflectiveInjector.Angular2 2.0.1 Komponententest mit Kern Injector

Das sieht etwa wie

@ViewChild('container', {read: ViewContainerRef}) container: ViewContainerRef; 
let inputProviders = [{ 
    provide: 'injectedInput', 
    useValue: inputValue 
}]; 
let resolvedInputs = ReflectiveInjector.resolve(inputProviders); 
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.container.parentInjector); 
let factory = componentInfo.factory.resolveComponentFactory(componentInfo.component); 
let component = factory.create(injector); 
this.container.insert(component.hostView); 

Dann sieht die dynamisch erzeugte Komponente wie diese

import {Component, Injector} from '@angular/core'; 
@Component({ 
    selector: 'mycomponent' 
}) 
export class MyComponent { 
    private id: string; 

    constructor(private injector: Injector) { 
     this.id = injector.get('injectedInput'); 
    } 
} 

Ich versuche, Unit-Tests für diese Komponente zu schreiben, die den Kern Injector-Modul verwendet. Ich erhalte die folgende Fehlermeldung:

Error: No provider for injectedInput!

Meine Spec-Datei wie folgt aussehen:

import { MyComponent } from 'here'; 
describe('MyComponent',() => { 
    beforeEach(() => { 
     TestBed.configureTestingModule({ 
      providers: [ 
       MyComponent 
      ] 
     }); 
    }); 

    let component: MyComponent; 

    beforeEach(inject([RigTransferSpeedPeriodComponent], _component => { 
     component = _component; 
    })); 

    {...my tests...} 
}); 

ich ein paar Sachen ausprobiert habe und überall gesucht, konnte aber niemanden, der dies zuvor finden.

Irgendeine Idee?

Vielen Dank!

Philippe

+0

nicht Sehen Sie den Punkt, warum Sie all das tun ... aber für mich sieht es so aus, als ob Ihr ElternInjektor die Komponente erstellt. Die Komponente selbst verwendet also auch den parentInjector, und der parentInjector kennt den injectedInput nicht. Vielleicht solltest du deine Absicht beschreiben und vielleicht gibt es eine andere Möglichkeit, es zu lösen, als die gesamte Injektionslogik neu zu verkabeln –

Antwort

0

experimentierte ein wenig mit plnkr, verwendet Ihr Problem als Beispiel ;-)

@Component({ 
    selector: 'my-component', 
    template: '' 
}) 
export class TestComponent { 
    constructor(
    private injector : Injector 
) { 
    injector.get('value1'); 
    } 
} 

describe('a test',() => { 
    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ TestComponent ], 
     providers: [ TestComponent ] 
    }); 
    }); 

    beforeEach(() => { 
    this.injector1 = ReflectiveInjector.resolveAndCreate([ 
     {provide: 'value1', useValue: 5} 
    ]); 

    }); 

    it('inject value',() => { 
    expect(this.injector1.get('value1')).toBe(5); 
    }); 

    describe('create component',() => { 
    it('with untouched injector should throw error',() => { 
     expect(() => TestBed.createComponent(TestComponent)).toThrowError(); 
    }) 

    it('with manipulated injector',() => { 
     let componentInjector = TestBed.get(Injector); 
     componentInjector.parent = this.injector1; 
     expect(TestBed.createComponent(TestComponent)).toBeTruthy(); 
    }) 

    it('with injectors in the wrong order',() => { 
     let componentInjector = TestBed.get(Injector); 
     let combinedInjector = ReflectiveInjector.fromResolvedProviders(this.injector1, componentInjector); 
     expect(() => combinedInjector.get(TestComponent)).toThrowError(); 
    }) 
    }); 
}); 

http://plnkr.co/edit/PlUUtTOZq8bPLQ5WdAbE?p=preview

bewiesen, dass es über die Reihenfolge der Injektoren ist

Verwandte Themen