实例化使用隔离范围进行测试的控制器

时间:2015-07-16 22:08:06

标签: angularjs unit-testing

所以我有一个控制器测试文件:

scope = $rootScope.$new();
ctrlInstance = $controller( 'formCtrl', { $scope: scope } );

这个控制器没有正确实例化,因为我传入的范围并不具有它通常具有的数据(由于从隔离范围传递)。

这些是我的formCtrl的前几行:

var vm = this;
vm.stats = angular.copy( vm.statsStuff ); 
vm.stats.showX = vm.stats.showY = true;

请注意,vm.statsStuff具有绑定到它的数据(由于相应指令中的' ='范围),但是当我实例化时,我不确定如何将这些值传递给它我的控制器在测试中。

任何帮助将不胜感激。

添加指令:

angular.module( 'myModule' )
    .directive( 'formStuff', function() {
        return {
            restrict: 'E',
            templateUrl: 'dir.tpl.html',
            scope: {
                statsStuff: '='
            },
            controller: 'formStuffCtrl',
            controllerAs: 'formCtrl',
            bindToController: true
        };
    } );
})();

2 个答案:

答案 0 :(得分:3)

angular-mocks模块有一个$controller服务,用于修饰“真实”服务,并允许传递第三个参数,包含在实例化之前绑定到控制器的数据。

所以你需要的只是

ctrlInstance = $controller('formCtrl', { $scope: scope }, { statsStuff: theStuff } );    

答案 1 :(得分:1)

在你升级到1.4之前(当这样做时,JB的回答方式),我会做以下几点来“模仿”第三个参数正在做什么(在某种程度上) *):

var $scope, ctrlInstance, createController;

beforeEach(function () {
  module('your_module');

  inject(function ($injector, $controller) {
    $scope = $injector.get('$rootScope').$new();

    createController = function (bindStuff) {
      ctrlInstance = $controller('formStuffCtrl', {
        $scope: $scope
      });

      Object.keys(bindStuff).forEach(function (key) {
        ctrlInstance[key] = bindStuff[key];
      });
    });
  });
});


it('exposes the "statsStuff stuff"', function () {
  var stats = { x: 500, y: 1000 };
  createController({ stats: stats });
  expect(ctrlInstance.stats).to.deep.equal(stats);
});

即使没有bindToController'仿真',我强烈建议使用createController实例化控制器的方式,因为它可以让您灵活地操作控制器依赖(不需要)另一个before|beforeEach块)。

*:我在某种程度上说,因为这是在实例化控制器之后附加属性,而bindToController在事先附加属性。所以两者之间可能存在一些差异。