2017-02-28 6 views
3

Angluar2モデルにバインドされた入力ボックスをテストできないようです。私はこれに少し新しいので、私と一緒に裸をしてください。Angular 2テスト入力ボックスバインディング

私はモデルに結合された入力ボックスを含む非常に基本的なAngular2コンポーネントを持っています。

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

次のテストを実行している同じ「ジョン」に未定義の期待得続ける:

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

は、ここでの背後にあるコードです。 私はテストに合格すると期待しています。

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

答えて

3

ので、カップルの事:

  1. あなたはコンポーネントが作成された後tickを呼び出す必要があります。完全にはわかりませんが、モデルバインドは非同期的に起こると思います。ティッキングなしでは、テストは失敗します。
  2. ディレクティブは、keyupではなく、inputイベントをリッスンします。 inputイベントが発生すると、ディレクティブはバインディングを更新します。

ここで(もPlunker上)完全なテストだ疑いで、時には例を探すのに最適な場所はsource code tests とき

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

    })); 
}); 

  • を参照してください。
+0

すばらしい答え。ありがとうございました! –

+0

'tick()'と 'input.dispatchEvent'トリックが私の命を救った! – elli0t

+0

ねえ、回答と質問自体のように。ここでダニ関数は何ですか?私は今、同じ状況にあります。入力にバインドされたngModelをテストする必要があります。そのティック()が必要ですか? –

関連する問題