单元测试包含ngbTypeahead

时间:2017-09-15 08:37:00

标签: angular unit-testing ng-bootstrap angular-ui-typeahead

我有一个包含带有3个输入文本的表单的组件。两个输入是纯文本框,一个是ngbTypeahead指向ng-bootstrap的文本框。 我的表单是使用FormBuilder(反应形式)构建的。

 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指令的输入,我不知道如何设置值(需要是Department对象而不是字符串): 我试过了,但它不起作用:

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

1 个答案:

答案 0 :(得分: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.
  }));

希望这有帮助。

相关问题