Angular2茉莉花单元测试组件与第三方指令

时间:2017-04-10 09:26:45

标签: angular jasmine karma-jasmine

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

在模板中我有这个:

function happySunshine(/* some inparameters */){
  // calculates and sets variables a, b(array) and c
  // return new Promise(function(resolve, reject) {
       // do stuff
       // resolve({a:a, b:[], c:c});
  // });
  return Promise.resolve({a:a, b:[], c:c});
}

happySunshine(/* some inparameters */)
.then(function({a, b, c}) {
  // does things with the variables a, b(array) and c
})

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

致电点击:

    <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>

不起作用 - 如果我试图寻找let droplist = fixture.debugElement.query(By.css('#droplist-label')).nativeElement; droplist.click(); 它是空的:

dropdown-menu

该指令似乎有一个用于click事件的hostlistener - 如何触发它以便ul可用?

2 个答案:

答案 0 :(得分:4)

我终于使用fakeAsync()解决了同一个pb:

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.detectChanges()的开头错过了fixture.whenStable().then(...)

另外,请记住将BsDropdownModule导入测试平台:

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

答案 1 :(得分:1)

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

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++;
        }
    });
}));