Angular 单击组件测试中的 select 选项
Angular click select option in component test
我尝试了以下方法来尝试单击 select 下拉列表 none 中的一个选项,其中的工作。
selectEl = fixture.debugElement.query(By.css('#dropdown'));
selectEl.nativeElement.options[3].nativeElement.dispatchEvent(new Event('click'));
selectEl.queryAll(By.css('option'))[3].nativeElement.click();
selectEl.nativeElement.options[3].nativeElement.click();
在每个 运行 fixture.detectChanges();
到 运行 变化检测之后,但是当我去检查元素值时它没有改变。 expect(selectEl.nativeElement.options[selectEl.nativeElement.selectedIndex].textContent).toBe('name2');
我是不是缺少一些简单的东西来让它工作?
更改下拉列表的选定选项的方法是设置下拉列表值,然后调度一个 change
事件。
你可以参考这个答案:
在你的情况下,你应该这样做:
const select: HTMLSelectElement = fixture.debugElement.query(By.css('#dropdown')).nativeElement;
select.value = select.options[3].value; // <-- select a new value
select.dispatchEvent(new Event('change'));
fixture.detectChanges();
您不必发送更改事件。
首先,您需要点击下拉菜单的触发器,我假设这是您的 selectEl
selectEl = fixture.debugElement.query(By.css('#dropdown'))
.
selectEl.click();
fixture.detectChanges();
在 detectChanges 之后,您的下拉菜单应该会打开。只有在这之后你才能从 fixture 中获得你的选项,因为之前它们不存在于你的 fixture 中。
我能够获得选项的唯一方法是执行 const selectOptions = fixture.debugElement.queryAll(By.css('.select-option'));
,其中“select-选项”是我放在选项上的 class。我在我的项目中使用 mat-select ,所以这可能是由于那个。
您可以通过 selectOptions[0].nativeElement.click();
单击第一个选项。之后您需要再次调用 fixture.detectChanges()
。
现在您 select 有了一个选项!
我能够通过 selectEl.innerText.trim()
获得现在 select 的值。不确定这是否是最好的方法,但它确实有效。 Trim 用于去除空格。
我对 Emmy 的回答做了一些扩展。这是用于 selecting material 下拉列表的有效 "helper" 方法。
import { By } from '@angular/platform-browser';
export default class TestUtils {
static selectDropdown(id: string, fixture: any): void {
const select = fixture.debugElement.query(By.css(`#${id}`)).nativeElement;
select.click();
fixture.detectChanges();
const selectOptions = fixture.debugElement.queryAll(By.css(`.${id}Option`));
selectOptions[5].nativeElement.click();
fixture.detectChanges();
}
}
这让您可以指定您想要 select(通过 ID)的下拉列表和您想要 select 的索引。此方法的唯一注意事项是您必须向下拉列表中的 mat-option 元素添加 class。示例:
<mat-option *ngFor="let trim of trims" value="{{trim}}" class="trimDropdownOption">{{trim}}</mat-option>
只需确保 mat-option 的 class 包含添加了 'Option' 的 ID。
这解决了 Emmy 的回答中的一个问题,即如果您在一个表单上有多个下拉菜单,您可以指定单击哪个 mat-option。
您可以通过在测试中引用它来使用上述扩展方法,如下所示:
TestUtils.selectDropdown('yearDropdown', 1, fixture);
expect(fixture.componentInstance.onYearChange).toHaveBeenCalled();
我可以提供的最简单的解决方案如下。
let selectElement: HTMLSelectElement = fixture.nativeElement.querySelector('#dropdown');
selectElement.selectedIndex = 3;
selectElement.dispatchEvent(new Event('change'));
首先,您通过 ID 获取元素,然后 select 按编号获取索引 在您的情况下,它是 3 然后通过调度事件将触发 change 事件。
我尝试了以下方法来尝试单击 select 下拉列表 none 中的一个选项,其中的工作。
selectEl = fixture.debugElement.query(By.css('#dropdown'));
selectEl.nativeElement.options[3].nativeElement.dispatchEvent(new Event('click'));
selectEl.queryAll(By.css('option'))[3].nativeElement.click();
selectEl.nativeElement.options[3].nativeElement.click();
在每个 运行 fixture.detectChanges();
到 运行 变化检测之后,但是当我去检查元素值时它没有改变。 expect(selectEl.nativeElement.options[selectEl.nativeElement.selectedIndex].textContent).toBe('name2');
我是不是缺少一些简单的东西来让它工作?
更改下拉列表的选定选项的方法是设置下拉列表值,然后调度一个 change
事件。
你可以参考这个答案:
在你的情况下,你应该这样做:
const select: HTMLSelectElement = fixture.debugElement.query(By.css('#dropdown')).nativeElement;
select.value = select.options[3].value; // <-- select a new value
select.dispatchEvent(new Event('change'));
fixture.detectChanges();
您不必发送更改事件。
首先,您需要点击下拉菜单的触发器,我假设这是您的 selectEl
selectEl = fixture.debugElement.query(By.css('#dropdown'))
.
selectEl.click();
fixture.detectChanges();
在 detectChanges 之后,您的下拉菜单应该会打开。只有在这之后你才能从 fixture 中获得你的选项,因为之前它们不存在于你的 fixture 中。
我能够获得选项的唯一方法是执行 const selectOptions = fixture.debugElement.queryAll(By.css('.select-option'));
,其中“select-选项”是我放在选项上的 class。我在我的项目中使用 mat-select ,所以这可能是由于那个。
您可以通过 selectOptions[0].nativeElement.click();
单击第一个选项。之后您需要再次调用 fixture.detectChanges()
。
现在您 select 有了一个选项!
我能够通过 selectEl.innerText.trim()
获得现在 select 的值。不确定这是否是最好的方法,但它确实有效。 Trim 用于去除空格。
我对 Emmy 的回答做了一些扩展。这是用于 selecting material 下拉列表的有效 "helper" 方法。
import { By } from '@angular/platform-browser';
export default class TestUtils {
static selectDropdown(id: string, fixture: any): void {
const select = fixture.debugElement.query(By.css(`#${id}`)).nativeElement;
select.click();
fixture.detectChanges();
const selectOptions = fixture.debugElement.queryAll(By.css(`.${id}Option`));
selectOptions[5].nativeElement.click();
fixture.detectChanges();
}
}
这让您可以指定您想要 select(通过 ID)的下拉列表和您想要 select 的索引。此方法的唯一注意事项是您必须向下拉列表中的 mat-option 元素添加 class。示例:
<mat-option *ngFor="let trim of trims" value="{{trim}}" class="trimDropdownOption">{{trim}}</mat-option>
只需确保 mat-option 的 class 包含添加了 'Option' 的 ID。
这解决了 Emmy 的回答中的一个问题,即如果您在一个表单上有多个下拉菜单,您可以指定单击哪个 mat-option。
您可以通过在测试中引用它来使用上述扩展方法,如下所示:
TestUtils.selectDropdown('yearDropdown', 1, fixture);
expect(fixture.componentInstance.onYearChange).toHaveBeenCalled();
我可以提供的最简单的解决方案如下。
let selectElement: HTMLSelectElement = fixture.nativeElement.querySelector('#dropdown');
selectElement.selectedIndex = 3;
selectElement.dispatchEvent(new Event('change'));
首先,您通过 ID 获取元素,然后 select 按编号获取索引 在您的情况下,它是 3 然后通过调度事件将触发 change 事件。