如何在 Angular 2 测试中测试下拉菜单切换操作?

3

我将尝试测试下拉切换功能。但是我无法让它正常工作。我已经在规范文件中导入了 BsDropdownModule。 注意:我正在使用 ngx-bootstrap。

这是我的尝试:

Html:

<div class="btnBox" dropdown placement="bottom right">
    <button class="btnIcon dropdown-toggle" dropdownToggle>
    </button>
    <ul class="btnOptionBox dropdown-menu dropdown-menu-right" *dropdownMenu>
       <li class="iconBtn" (click)="someFun()" type="button"><span>Edit</span></li>
       <li class="iconBtn" (click)="someFun1()" type="button"><span>Delete</span></li>
    </ul>
 </div>

测试规范:

it("Should show options when toggle option is clicked",() => {
     fixture.detectChanges();
     let toggleButton = fixture.debugElement.queryAll(By.css('[dropdownToggle]'));
     toggleButton[0].nativeElement.click();
     fixture.detectChanges();
     /*Unable to access li tag directly. That's why I have used it's parent*/
     let list = fixture.debugElement.queryAll(By.css('div.ellipsisBox'));  
     console.log(list[0]); /*Shows the list in the children array*/
     console.log(list[0].children);  /*Doesn't show the list*/
});

有人能提供正确的方法吗?这与IT技术有关。

你好,能告诉我你是怎么在spec中导入BsDropdownModule的吗?我尝试过,但是会出现很多静态注入器错误。我按照你的解决方案尝试了一下,但是还是遇到了同样的问题,即使点击按钮后,ul元素仍然没有出现在dom中。 - ChaoticTwist
你尝试添加FormsModule了吗?你是否因BsDropdownModule而收到注入器错误? - Sanju
1个回答

7

我已经成功解决了这个问题。这只是一个愚蠢的错误。列表中的数据是由一个异步过程填充的。因此,当点击下拉按钮后,我应该使用fakeAsynctick()。在将数据填充到列表中之前,视图已经被更新了。这就导致了问题。以下是修复后的代码:

it("Should show options when toggle option is clicked",fakeAsync(() => {
     fixture.detectChanges();
     let toggleButton = fixture.debugElement.queryAll(By.css('[dropdownToggle]'));
     toggleButton[0].nativeElement.click();
     tick();
     fixture.detectChanges();
     let list = fixture.debugElement.queryAll(By.css('ul.btnOptionBox'));  
     console.log(list[0]);
}));

谢谢,帮了我很大的忙。不确定这是否是一个愚蠢的错误 - 我认为知道和记住何时必须使用fakeAsync / tick并不容易。 - Benjamin Peter
我没有看到你的期望,难道你不需要对这个测试有一个期望吗? - Girum
@Girum,必须有期望,但我没有包含它,因为它与解释我的问题无关。 - Sanju
1
谢谢Sanju,我明白了,你的例子很棒。 - Girum
嗨,@Sanju,在点击下拉菜单后,我能否在这种情况下使用async await?像这样await SleepForASecond(0)。这是我在SleepForASecond中的代码:static sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } static async SleepForASecond(ms) { await this.sleep(ms); } - Anshita Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接