如何测试内部控制器,以角度形式加载选择控件的数据

时间:2015-06-18 20:53:41

标签: angularjs angular-formly

我有一个ui-select字段

{
  key: 'data_id',
  type: 'ui-select',
  templateOptions: {
    required: true,
    label: 'Select label',
    options: [],
    valueProp: 'id',
    labelProp: 'name'
  },
  controller: function($scope, DataService) {
    DataService.getSelectData().then(function(response) {
      $scope.to.options = response.data;
    });
  }
}

如何在单元测试中访问该内部控制器并检查select字段的数据加载是否真的有效?

更新 测试的一个例子可能是这样的:

var initializePageController = function() {
  return $controller('PageCtrl', {
    '$state': $state,
    '$stateParams': $stateParams
  });
};

var initializeSelectController = function(selectElement) {
  return $controller(selectElement.controller, {
    '$scope': $scope
  });
};

然后测试用例看起来像:

it('should be able to get list of data....', function() {
   $scope.to = {};
   var vm = initializePageController();

   $httpBackend.expectGET(/\/api\/v1\/data...../).respond([
     {id: 1, name: 'Data 1'},
     {id: 2, name: 'Data 2'}
   ]);

   initializeSelectController(vm.fields[1]);
   $httpBackend.flush();

   expect($scope.to.options.length).to.equal(2);
});

2 个答案:

答案 0 :(得分:0)

你可以通过几种方式做到这一点。一种选择是测试包含此配置的控制器。因此,如果您将字段配置设置为$scope.fields,请执行以下操作:

$scope.fields = [ { /* your field config you have above */ } ];

然后在你的测试中你可以做类似的事情:

$controller($scope.fields[0].controller, { mockScope, mockDataService });

然后做你的断言。

答案 1 :(得分:0)

我最近为使用ui-select的类型编写了一些测试。我实际上创建了一个formly-form然后在那里运行测试。我使用以下助手

function compileFormlyForm(){
    var html = '<formly-form model="model" fields="fields"></formly-form>';

    var element = compile(html)(scope, function (clonedElement) {
        sandboxEl.html(clonedElement);
    });

    scope.$digest();
    timeout.flush();
    return element;
}

function getSelectController(fieldElement){
    return fieldElement.find('.ui-select-container').controller('uiSelect');
}

function getSelectMultipleController(fieldElement){
    return fieldElement.find('.ui-select-container').scope().$selectMultiple;
}

function triggerEntry(selectController, inputStr) {
    selectController.search = inputStr;

    scope.$digest();
    try {
        timeout.flush();
    } catch(exception){
        // there is no way to flush and not throw errors if there is nothing to flush.
    }
}

// accepts either an element or a select controller
function triggerShowOptions(select){
    var selectController = select;
    if(angular.isElement(select)){
        selectController = getSelectController(select);
    }
    selectController.activate();
    scope.$digest();
}

其中一项测试的例子

it('should call typeaheadMethod when the input value changes', function(){
    scope.fields = [
        {
            key: 'selectOneThing',
            type: 'singleSelect'
        },
        {
            key: 'selectManyThings',
            type: 'multipleSelect'
        }
    ];

    scope.model = {};

    var formlyForm = compileFormlyForm();
    var selects = formlyForm.find('.formly-field');

    var singleSelectCtrl = getSelectController(selects.eq(0));
    triggerEntry(singleSelectCtrl, 'woo');
    expect(selectResourceManagerMock.searchAll.calls.count()).toEqual(1);

    var multiSelectCtrl = getSelectController(selects.eq(1));
    triggerEntry(multiSelectCtrl, 'woo');
    expect(selectResourceManagerMock.searchAll.calls.count()).toEqual(2);
});