2016-11-04 55 views
6

我使用ComponentFactoryResolver動態創建組件,並使用ReflectiveInjector動態傳遞它們的輸入。Angular2 2.0.1核心噴油器組件單元測試

這看起來像左右

@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); 

然後動態創建的組件看起來像這樣

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

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

我想要編寫單元測試使用的核心注射器模塊該組件。我收到以下錯誤:

Error: No provider for injectedInput!

我的規格文件是這樣的:

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

    let component: MyComponent; 

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

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

我已經嘗試了一堆東西,到處搜尋,但沒找到人誰這樣做過。

有什麼想法?

非常感謝!

菲利普

+0

不看看你爲什麼要這樣做......但對我來說,它看起來像你的parentInjector創建組件。所以組件本身也使用parentInjector,並且parentInjector不知道injectInput。也許你應該描述你的意圖,也許還有另一種解決方法,而不是重新注入整個注入邏輯 –

回答

0

嘗試了一下用plnkr,用你的問題,例如;-)

@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

證明,它是關於噴射器的順序