简体   繁体   中英

how to inject IterableDiffers “service” into a unit test

I am trying add unit tests for this component located in https://github.com/czeckd/angular-dual-listbox .... But I got an error because the component has a dependency with the type: "IterableDiffers"

export class DualListComponent implements DoCheck, OnChanges { ....
constructor(private differs: IterableDiffers) {} ...

My first try looks like on this way:

 import { async, ComponentFixture, TestBed} from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { DebugElement } from '@angular/core'; import { TranslateModule } from 'ng2-translate/ng2-translate'; import { DualListComponent } from './dual-list.component'; describe('DashboardHeroComponent when tested directly', () => { let comp: DualListComponent; let fixture: ComponentFixture<DualListComponent>; let heroEl: DebugElement; // async beforeEach beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [DualListComponent], imports: [ TranslateModule.forRoot()] }) .compileComponents(); // compile template and css })); // synchronous beforeEach beforeEach(() => { let srouce: Array < any > = [ { key: 1, station: 'Antonito', state: 'CO' }, { key: 2, station: 'Big Horn', state: 'NM' }, { key: 3, station: 'Sublette', state: 'NM' }, { key: 32, station: 'Eureka', state: 'CO' } ]; fixture = TestBed.createComponent(DualListComponent); comp = fixture.componentInstance; heroEl = fixture.debugElement.query(By.css('.hero')); // find hero element comp.key = 'key'; comp.display = 'station'; comp.source = srouce; comp.destination = []; fixture.detectChanges(); // trigger initial data binding }); it('should display hero name', () => { expect(comp.available.list.length).toEqual(4); }); }); 

And the error what I got after run ;"npm test" is:

TypeError: Cannot read property 'diff' of undefined   

the error message is not too clear itself but the reason is because try use the object "differs" what should be load in the constructor.

any idea how to add it in the test?

update 1 after follow the instructions from Tiep Phan and insert "IterableDiffers" as a provider ... I got the issue: "Can't resolve all parameters for IterableDiffers"... I can understand the error but don't know how to solve it...the error basically is because the constructor of IterableDiffers class accept an array of type "IterableDifferFactory".

constructor(factories: IterableDifferFactory[]);

add your dependencies to NgModule declaration

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

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [DualListComponent],
        imports: [ TranslateModule.forRoot()],
        providers: [
            //other provider
            IterableDiffers
        ]
    })
        .compileComponents(); // compile template and css
}));

I don't understant why you want to inject IterableDiffers . It works well.

Your error happens here

buildAvailable(source:Array<any>) : boolean {
    let sourceChanges = this.sourceDiffer.diff(source);

this.sourceDiffer is undefined. If you take a look at source code you can notice that sourceDiffer is initialized within ngOnChanges . So you need to call ngOnChanges

Look at this article https://medium.com/@christophkrautz/testing-ngonchanges-in-angular-components-bbb3b4650ee8

Here is example for your case:

fixture = TestBed.createComponent(DualListComponent);
comp = fixture.componentInstance;
heroEl = fixture.debugElement.query(By.css('.hero')); // find hero element
comp.key = 'key';
comp.display = 'station';
comp.source = srouce;
comp.destination = [];

comp.ngOnChanges({ // add this
    source: new SimpleChange(null, srouce, true)
});

See it in action in Plunker Example

Another way is using temporary component as described in article above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM