如何为单元测试触发角度ui-select指令的更改事件?

时间:2016-05-31 18:39:04

标签: angularjs

我想测试使用ui-select指令的代码:

<ui-select class="firstSelect"
        ng-model="singleFilter.selectedField" 
        ng-disabled="vm.filterDisabled" 
        on-select="vm.itemSelected(singleFilter)"                      
        theme="bootstrap">
        <ui-select-match placeholder="...">
              {{$select.selected.name}}</ui-select-match>
        <ui-select-choices repeat="field in singleFilter.fields | filter: $select.search">
                    <span ng-bind-html="field.name | highlight: $select.search"></span>
      </ui-select-choices>
</ui-select>

问题是:当我对使用该指令的代码进行单元测试时,如何在此控件上触发更改事件?

2 个答案:

答案 0 :(得分:1)

我有同样的挫败感。我在ui-select spec中发现执行on-select函数需要在单击其中一个选项后调用$timeout.flush()

这样的事情(不要忘记注入$ timeout):

compiledUiSelectEl.find('.ui-select-choices-row-inner')[0].click();
scope.$digest();
$timeout.flush();

包括来自ui-select spec

的测试的相关部分
function compileTemplate(template) {
  var el = $compile(angular.element(template))(scope);
  scope.$digest();
  return el;
}

function clickItem(el, text) {

  if (!isDropdownOpened(el)) {
    openDropdown(el);
  }

  $(el).find('.ui-select-choices-row div:contains("' + text + '")').click();
  scope.$digest();
}


it('should invoke select callback on select', function () {

  scope.onSelectFn = function ($item, $model, $label) {
    scope.$item = $item;
    scope.$model = $model;
  };
  var el = compileTemplate(
    '<ui-select on-select="onSelectFn($item, $model)" ng-model="selection.selected"> \
      <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \
      <ui-select-choices repeat="person.name as person in people | filter: $select.search"> \
        <div ng-bind-html="person.name | highlight: $select.search"></div> \
        <div ng-bind-html="person.email | highlight: $select.search"></div> \
      </ui-select-choices> \
    </ui-select>'
  );

  expect(scope.$item).toBeFalsy();
  expect(scope.$model).toBeFalsy();

  clickItem(el, 'Samantha');
  $timeout.flush();


  expect(scope.selection.selected).toBe('Samantha');

  expect(scope.$item).toEqual(scope.people[5]);
  expect(scope.$model).toEqual('Samantha');

});

答案 1 :(得分:0)

您的单元测试应该直接调用itemSelected函数。因此,一旦在单元测试中创建控制器的实例,只需调用:

vm.itemSelected(mockData);