2017-02-28 5 views
3

Ich kann nicht scheinen, ein Eingabefeld zu testen, das an ein Angluar2-Modell gebunden ist. Ich bin ein wenig neu, also bitte nimm mich mit.Angular 2 Testing Eingabefeld Bindung

Ich habe eine sehr einfache Angular2-Komponente, die ein Eingabefeld enthält, das an ein Modell gebunden ist.

<form> 
    <input type="text" [(ngModel)]="searchTerm" name="termsearchTerm" (keyup)="search()" value=""/> 
</form> 

Hier ist der Code hinter:

import { Component, Input, Output, EventEmitter } from '@angular/core'; 

@Component({ 
    moduleId: module.id, 
    selector: 'sc-search', 
    templateUrl: 'search.component.html' 
}) 

export class SearchComponent { 
    @Input() data: any; 
    @Output() onSearchTermChanged = new EventEmitter<string>(); 
    private searchTerm: string; 

    search() { 
     this.onSearchTermChanged.emit(this.searchTerm); 
    } 
} 

Wenn Sie den folgenden Test läuft immer gleich 'John' undefined Erwartete zu werden. Ich erwarte, dass der Test bestanden wird.

searchableHierarchyComponentFixture.detectChanges(); 

    let termInputDbg = searchableHierarchyComponentFixture.debugElement.query(By.css('input[name="termsearchTerm"]')); 
    let input = searchableHierarchyComponentFixture.nativeElement.querySelector('input'); 

    input.value = 'John'; 

    let evt = document.createEvent('Event'); 
    evt.initEvent('keyup', true, false); 

    termInputDbg.triggerEventHandler('keyup', null); 
    input.dispatchEvent(evt); 


    tick(50); 
    searchableHierarchyComponentFixture.detectChanges(); 
    searchableHierarchyComponentFixture.whenStable(); 
    expect(searchableHierarchyComponentFixture.componentInstance.searchTerm).toEqual('John'); 

Antwort

3

So ein paar Dinge:

  1. Sie müssen tick aufzurufen, nachdem die Komponente erstellt wird. Nicht ganz sicher, aber ich denke, die Bindung des Modells passiert asynchron. Ohne zu ticken, wird der Test fehlschlagen.
  2. Die Richtlinie überwacht das Ereignis input, nicht das keyup. Wenn das Ereignis input auftritt, aktualisiert die Direktive die Bindungen.

ist der komplette Test (auch auf Plunker)

import { Component } from '@angular/core'; 
import { FormsModule } from '@angular/forms'; 
import { TestBed, fakeAsync, tick } from '@angular/core/testing'; 
import { By } from '@angular/platform-browser'; 

@Component({ 
    selector: 'test', 
    template: ` 
    <form> 
     <input type="text" [(ngModel)]="query" name="query" /> 
    </form> 
    ` 
}) 
class TestComponent { 
    query: string; 
} 

describe('TestComponent: ngModel',() => { 

    let fixture; 
    let component; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     imports: [FormsModule], 
     declarations: [TestComponent] 
    }); 
    fixture = TestBed.createComponent(TestComponent); 
    component = fixture.componentInstance; 
    }); 

    it('should change the value', fakeAsync(() => { 
    let input = fixture.debugElement.query(By.css('input')).nativeElement; 

    fixture.detectChanges(); 
    tick(); 

    expect(component.query).toBeFalsy(); 

    input.value = 'Hello World'; 
    input.dispatchEvent(new Event('input')); 
    tick(); 

    expect(component.query).toBe('Hello World'); 

    })); 
}); 

See auch

  • im Zweifel Wenn manchmal der beste Platz für Beispiele zu suchen ist die source code tests
+0

Fantastische Antwort. Vielen Dank! –

+0

Die Tricks 'tick()' und 'input.dispatchEvent' haben mein Leben gerettet! – elli0t

+0

Hey Leute, wie eine Antwort und die Frage an sich. Aber was ist Tick-Funktion hier? Ich habe jetzt dieselbe Situation. und möchte ngModel testen, das an die Eingabe gebunden ist. Brauche ich das Häkchen()? –