修改角度控制器单元测试的$ scope值

时间:2014-04-05 02:53:02

标签: angularjs unit-testing karma-runner

所有

我有一个AngularJS控制器的单元测试套件,它遵循模式beforeEach()

var ResourcesCtrl,
    scope, rootScope, loc, ctrl;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $location) {
    scope = {};
    rootScope = {};
    loc = $location;
    ctrl = $controller;
    scope.instanceName = 'TestInstance';


    ResourcesCtrl = $controller('ResourcesCtrl', {
      $scope: scope,
      $rootScope: rootScope,
      $location: loc
    });
  }));

然后一堆it()块带有断言/期望所有都按预期工作。

现在我需要做的是,在我添加的一个测试用例中,改变scope.instanceName的值;但是,看起来即使我在it()测试用例中更改了它的值,也没有反映在控制器的范围内。我已经尝试在测试用例中使用新范围实例化控制器,但这也没有用。

所以我的问题如下:如何更改/覆盖beforeEach()设置中传递给控制器​​的变量?

2 个答案:

答案 0 :(得分:5)

这里的问题是对$controller的调用发生在beforeEach中,使用当时可用的任何范围变量。您希望能够在调用控制器之前更改scope变量。一种选择是使用在每个规范中调用的init函数,以便您可以准确控制控制器何时被调用:

beforeEach(inject(function ($controller, $location) {
  scope = {};
  rootScope = {};
  loc = $location;
  ctrl = $controller;
  scope.instanceName = 'TestInstance';

  this.init = function() {
    ResourcesCtrl = $controller('ResourcesCtrl', {
      $scope: scope,
      $rootScope: rootScope,
      $location: loc
    });
  }
}));

...

it("should do something", function() {
  scope.instanceName = "NewName";
  this.init();
  ...
});

请注意,这意味着必须在文件中的每个规范中调用this.init

答案 1 :(得分:2)

在您的beforeEach中将$ rootScope添加到参数列表中并分配以下变量,如

scope = $rootScope.$new();
rootScope = $rootScope;

因为它们来自angular的$ rootScope,你可以根据需要调用$ apply()。