【问题标题】:Angular2 jasmine unit test component with third party directiveAngular2 茉莉花单元测试组件与第三方指令
【发布时间】:2017-04-10 09:26:44
【问题描述】:

组件是https://github.com/valor-software/ngx-bootstrap 下拉菜单。

在模板中我有这个:

    <span dropdown placement="bottom right">
      <a id="droplist-label" href="javascript:void(0)" dropdownToggle>
          <span>{{conf.title}}</span>
      </a>
      <ul class="dropdown-menu pull-right" *dropdownMenu>
        <li *ngFor="let item of items">
          <a class="dropdown-item" (click)="listClick(item.value)" href="javascript:void(0)">{{item.label}}</a>
        </li>
      </ul>
    </span>

在单击标签之前不会添加 ul - 因此我无法在测试中访问它。

调用点击:

let droplist = fixture.debugElement.query(By.css('#droplist-label')).nativeElement;
droplist.click();

不起作用 - 如果我尝试查找 dropdown-menu 它是空的:

it('should test if droplist has title',  async(() => {
    fixture.detectChanges();
    let droplist = fixture.debugElement.query(By.css('#droplist-label')).nativeElement;
    droplist.click();

    fixture.whenStable().then(() => {
        let droplistOptions = fixture.debugElement.queryAll(By.css('.dropdown-item'));
        expect(droplistOptions.length).toBeGreaterThan(0);
    });
}));

该指令似乎有一个用于单击事件的主机侦听器 - 我如何触发它以便 ul 可用?

【问题讨论】:

  • 似乎组件在内部使用
  • 对我来说同样的问题...
  • @M'sieurToph' 看看我的回答。
  • 谢谢 ... 看看我的 ;)

标签: angular jasmine karma-jasmine


【解决方案1】:

我终于用fakeAsync()解决了同样的问题:

it('should render submenus', fakeAsync(() => {

  fixture.detectChanges(); // update the view

  // trig submenus opening
  let toggleButtons = fixture.debugElement.nativeElement.querySelectorAll('[dropdownToggle]');
  toggleButtons.forEach(b => b.click());


  tick();                  // wait for async tasks to end
  fixture.detectChanges(); // update the view

  // then count how many items you got for each submenus.
  let droplistOptions1= fixture.debugElement.nativeElement.querySelectorAll('#first-ul > li')
  let droplistOptions2= fixture.debugElement.nativeElement.querySelectorAll('#second-ul > li')
  let droplistOptions3= fixture.debugElement.nativeElement.querySelectorAll('#third-ul > li')
  expect(droplistOptions1.length).toEqual(3);
  expect(droplistOptions2.length).toEqual(5);
  expect(droplistOptions3.length).toEqual(2);
}));

但我确信可以使用 async() 来做到这一点:我猜你在最初的尝试中只是在 fixture.whenStable().then(...) 的开头错过了 fixture.detectChanges()


另外,记得将 BsDropdownModule 导入您的测试平台:

import { BsDropdownModule} from 'ngx-bootstrap/dropdown';
...
TestBed.configureTestingModule({
  imports: [
    BsDropdownModule.forRoot(),
  ],
  ...
});

【讨论】:

    【解决方案2】:

    这是我针对上述问题提出的解决方案 - 使用子元素来获取内部元素。

    it('should test if droplist has listed correct values',  async(() => {
        comp.isOpen = true;
        fixture.detectChanges();
        fixture.whenStable().then(() => {
            let droplist = fixture.debugElement.query(By.css('.dropdown-menu'));
            fixture.detectChanges();
            expect(droplist.children.length).toBeGreaterThan(0);
            let i = 0;
            for(let item of droplist.children) {
                let anchorElement = item.children[0].nativeElement;
                expect(anchorElement.innerText).toBe(droplistItems[i].label);
                expect(anchorElement.getAttribute('data-value')).toBe(droplistItems[i].value);
                i++;
            }
        });
    }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 2022-01-23
      • 2020-11-25
      • 1970-01-01
      • 2016-07-13
      相关资源
      最近更新 更多