2017-01-25 2 views
2

Mein Problem ist genau die gleiche wie How do I trigger a ngModel model update in an Angular 2 unit test?angular2 Unit-Test nicht Eingangsänderungserfassungs

ich etwas Dummes in meinem Test tun müssen. Könnte jemand irgendwelche offensichtliche Fehler weisen darauf hin, dass ich

mit Blick auf bin

Komponente

@Component({ 
    moduleId: module.id, 
    selector: 'od-tree', 
    templateUrl: 'tree.component.html', 
    styleUrls: ['tree.component.css'], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class TreeComponent implements OnInit, OnChanges, AfterViewChecked { 
    @Input() allResources: { items: {} }; 
    @Input() resourceGroups = { items: {} }; 
    @Input() selectedNodes: ITree.SelectedNode[]; 
    @Input() showIcons: boolean; 
    @Input() showCheckboxes: boolean; 
    @Input() omitAncillaryDBs: boolean; 

    @Output() selectNode = new EventEmitter<any>(); 

    searchResource$ = new Subject<string>(); 
    searchField = ''; 
    tabs = [ 
    { title: TABS.ALL_RESOURCES, active: true }, 
    { title: TABS.RESOURCE_GROUPS, active: false } 
    ]; 
    inSearchMode = false; 
    trees = { 
    ALL_RESOURCES: { 
     searchText: null, 
     tree: [] 
    }, 
    RESOURCE_GROUPS: { 
     searchText: null, 
     tree: [] 
    } 
    }; 

    private _allResourcesTreeState = []; 
    private _resourceGroupsTreeState = []; 
    private ancillaryDBList = ['App-Services', 'Documents', 'Extensions', 'Fab', 'Last-Login', 
    'Meters', 'Modules', 'Schemas', 'Security', 'Triggers']; 

    constructor(private _cd: ChangeDetectorRef) { } 
... 
... 
... 
} 

Vorlage

<div class="input-with-icon"> 
     <i class="icon-search"></i> 
     <input type="text" [(ngModel)]="searchField" name="searchField" class="form-control" id="search-resources" placeholder="Search" (ngModelChange)="searchResource$.next(searchField)"> 
     </div> 
... (truncated) 
.... 
.... 

Unit-Test

describe('tree component',() => { 
    //let activatedRoute: ActivatedRouteStub; 
    let comp: TreeComponent; 
    let fixture: ComponentFixture<TreeComponent>; 
    let de: DebugElement; 
    let el: HTMLElement; 


    beforeEach(async(() => { 
     TestBed.configureTestingModule({ 
     imports: [TreeModule], 
     }) 
     .compileComponents(); 
    })); 

    beforeEach(() => { 
     fixture = TestBed.createComponent(TreeComponent); 
     comp = fixture.componentInstance; 
     de = fixture.debugElement; 
     el = de.nativeElement; 
     comp.ngOnInit(); 
     fixture.detectChanges(); 
    }); 


    it('should bind value to ngmodel',() => { 
     let inputEl = de.query(By.css('input#search-resources')) 
     inputEl.nativeElement.value = 'node'; 
     inputEl.triggerEventHandler('input', {target: inputEl.nativeElement}); 
     fixture.detectChanges(); 
     expect(comp.searchField).toEqual('node'); 
     }); 

// another approach 
    it('should filter resources when used in host component',fakeAsync(() => { 
     let inputEl = de.query(By.css('input#search-resources')); 
     inputEl.nativeElement.value = 'node'; 
     dispatchEvent('input', inputEl.nativeElement); 
     tick(); 
     fixture.detectChanges(); 
     expect(de.queryAll(By.css('li.host-leaf:not([hidden])')).length).toEqual(2, 'should show filtered hosts'); 
    })); 

    } 
+0

Update Ihr Beitrag mit ** ** TreeComponent – Aravind

Antwort

3

Dies ist ein bekanntes Problem bei der Implementierung detectChanges aktuelle Testbed(), wenn die Verwendung in Verbindung mit OnPush Erkennungsstrategie ändern. Sie können hier mehr darüber lesen. Sehr nervig.

Es stellt sich heraus, dass @Input Änderungen nicht von der aktuellen Komponente selbst, sondern von der übergeordneten Komponente ausgelöst wird.

Hier ist, was ich tat, um meine Tests arbeiten mit Winkel v2.4

fixture.changeDetectorRef['internalView']['compView_0'].markAsCheckOnce(); 
fixture.detectChanges(); 

https://github.com/angular/angular/issues/12313

+0

huh! vielen Dank. Ich habe es nicht versucht, aber ich werde diese Antwort akzeptieren. – Sudhakar

0

Sie müssen das FormsModule in das Testmodul importieren, damit die ngModel-Bindungen funktionieren.

beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
    imports: [ 
    TreeModule 
    FormsModule 
    ] 
    }) 
    .compileComponents(); 
})); 
+0

FormsModule zu machen, ist bereits in TreeModule importiert. Ich habe Ihren Vorschlag auch versucht, aber nicht geholfen. – Sudhakar