All,
所有,
I have a unit test suite for a AngularJS controller that follows the pattern beforeEach()
:
我有一个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
});
}));
Then a bunch of it()
blocks with assertions/expect that all work as expected.
然后一堆it()阻塞断言/期望所有工作按预期工作。
Now what I need to do, in just one of the test cases I'm adding, is change the value of scope.instanceName
; however, it appears that even if I change its value inside the it()
test case, that's not reflected in the scope of the controller. I have tried instantiating the controller with a new scope inside the test case, but that hasn't worked either.
现在我需要做的是,在我添加的一个测试用例中,更改scope.instanceName的值;但是,看起来即使我在it()测试用例中更改了它的值,也没有反映在控制器的范围内。我已经尝试在测试用例中使用新范围实例化控制器,但这也没有用。
So my question is the following: how can I change/override variables that were passed to the controller in the beforeEach()
setup?
所以我的问题如下:如何更改/覆盖在beforeEach()设置中传递给控制器的变量?
2 个解决方案
#1
5
The problem here is that the call to $controller
occurs in the beforeEach using whatever scope variables are available to it at that time. You want to be able to change the scope
variable before the controller is called. One option is to use an init
function which is called in each spec so that you can control exactly when the controller gets called:
这里的问题是对$ controller的调用发生在beforeEach中,使用当时可用的任何范围变量。您希望能够在调用控制器之前更改范围变量。一种选择是使用在每个规范中调用的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();
...
});
Note that this means that this.init
must be called in every spec in the file.
请注意,这意味着必须在文件的每个规范中调用this.init。
#2
2
in your beforeEach add $rootScope to the parameter list and assign the following variables like this
在您的beforeEach中,将$ rootScope添加到参数列表中,并像这样分配以下变量
scope = $rootScope.$new();
rootScope = $rootScope;
since they come from angular's $rootScope you can call $apply() if needed.
因为它们来自angular的$ rootScope,你可以根据需要调用$ apply()。
#1
5
The problem here is that the call to $controller
occurs in the beforeEach using whatever scope variables are available to it at that time. You want to be able to change the scope
variable before the controller is called. One option is to use an init
function which is called in each spec so that you can control exactly when the controller gets called:
这里的问题是对$ controller的调用发生在beforeEach中,使用当时可用的任何范围变量。您希望能够在调用控制器之前更改范围变量。一种选择是使用在每个规范中调用的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();
...
});
Note that this means that this.init
must be called in every spec in the file.
请注意,这意味着必须在文件的每个规范中调用this.init。
#2
2
in your beforeEach add $rootScope to the parameter list and assign the following variables like this
在您的beforeEach中,将$ rootScope添加到参数列表中,并像这样分配以下变量
scope = $rootScope.$new();
rootScope = $rootScope;
since they come from angular's $rootScope you can call $apply() if needed.
因为它们来自angular的$ rootScope,你可以根据需要调用$ apply()。