2017-09-15 42 views
1

我有一個組件包含一個帶有3個輸入文本的表單。兩個輸入是純文本框,一個是ngbTypeahead指向ng-bootstrap的文本框。 我的表單是使用FormBuilder(反應形式)構建的。單元測試一個包含ngbTypeahead的組件

this.form = fb.group({ 
    department: [''], 
    name: ['', Validators.required], 
    location: ['', Validators.required] 
}); 

我的模板是這樣的:

<input type="text" class="form-control" formControlName="name"/> 
... 
<input type="text" class="form-control" formControlName="location"/> 
... 
<input 
    type="text" 
    class="form-control" 
    formControlName="department" 
    [ngbTypeahead]="autocompleteDepartments" 
    [resultFormatter]="formatDepartment" 
    [inputFormatter]="formatDepartment"/> 

組件包含功能ngbTypeahead

autocompleteDepartments(text$: Observable<string>): Observable<Department> { 
    .... 
} 
formatDepartment(department: Department) { 
    return department.name; 
} 

所以this.form.department.value不是一個字符串,但像這樣的對象:

interface Department { 
    id: number; 
    name: string; 
    foo: boolean; 
    bar: number; 
    ... 
} 

一切正常。

現在我想單元測試我的組件,爲此我需要爲三個輸入中的每一個設置一個值。 對於兩個純投入,沒有問題:

const nameHtmlEl = <HTMLInputElement>fixture.debugElement.query(By.css('[formControlName="name"]')).nativeElement; 
nameHtmlEl.value = "Toto"; 
nameHtmlEl.dispatchEvent(new Event('input')); 

但與ngbTypeahead指令輸入,我不知道如何設置的值(即必須是處對象,而不是一個字符串): 我試過了,但它不起作用:

const departmentHtmlEl = /*<HTMLInputElement>*/ fixture.debugElement.query(By.css('[formControlName="department"]')).nativeElement; 
departmentHtmlEl.value = <Department>{id: 10, name: "Foo", ...}; 
departmentHtmlEl.dispatchEvent(new Event('input')); 

回答

0

我相信你試圖模擬Typeahead的一個過濾項目的選擇。

我會去了解這個的辦法是仍設置您正在搜索密鑰字符串:

departmentHtmlEl.value = 'Foo'; 

假設你的名字搜索。

然後,我會模擬選擇。這個你可以通過

getWindowLinks(fixture.debugElement)[0].triggerEventHandler('click', {}); 

其中getWindowLinks做的是:

function getWindowLinks(element: DebugElement): DebugElement[] { 
    return Array.from(element.queryAll(By.css('button.dropdown-item'))); 
} 

此外,你將不得不使用fakeAsync,使這項工作。樣品測試看起來像這樣:

it('sample test', fakeAsync(() => { 
    const departmentHtmlEl = /*<HTMLInputElement>*/ fixture.debugElement.query(By.css('[formControlName="department"]')).nativeElement; 
    departmentHtmlEl.value = 'Foo'; 
    fixture.detectChanges(); 

    tick(300); 
    // this should be more than the number on debounceTime you are using for the search 

    getWindowLinks(fixture.debugElement)[0].triggerEventHandler('click', {}); 
    fixture.detectChanges(); 

    tick(300); 

    // your expectation code here. 
    })); 

希望這會有所幫助。