在AngularJs控制器测试$范围与$过滤器的依赖 [英] Testing $scope in AngularJs controller with dependency on $filter
问题描述
我已经通过了一些教程和基本的例子走了,但我有一个很难写单元测试我控制器。我见过code片段实例化控制器,让角注入而这又是用来创建一个新的范围的
$ rootScope
对象code>对象控制器。但我不明白,为什么控制$范围
? 未定义
I've gone through a few tutorials and basic examples but I'm having a hard time writing unit tests for my controller. I've seen code snippets instantiating controllers and letting angular inject the $rootScope
object which in turn is used to create a new scope
object for the controller. But I can't figure out why ctrl.$scope
? is undefined:
describe('EmployeeCtrl', function () {
var scope, ctrl, $httpBackend;
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, $filter) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
ctrl = $controller('EmployeeCtrl', { $scope: scope});
expect(ctrl).not.toBeUndefined();
expect(scope).not.toBeUndefined(); //<-- PASS!
expect(ctrl.$scope).not.toBeUndefined(); //<-- FAIL!
}));
});
我结束了使用范围
变量代替控制$范围
但当时我的第一次测试中,我couldn T弄清楚如何进行单元测试我的控制器内的函数变量
I ended up using the scope
variable instead of ctrl.$scope
but then on my first test I couldn't figure out how to unit test a function variable inside my controller:
控制器:
function EmployeeCtrl($scope, $http, $filter, Employee) {
var searchMatch = function (haystack, needle) {
return false;
}
}
破碎单元测试:
it('should search ', function () {
expect(ctrl.searchMatch('numbers','one')).toBe(false);
});
这是我所得到的
类型错误:对象#没有方法'searchMatch
TypeError: Object # has no method 'searchMatch'
你怎么测试的功能?作为一种变通方法,我搬到我的方法到$范围,所以我可以测试 scope.searchMatch
但我想知道,如果这是唯一的办法。
How do you test that function? As a workaround I moved my method to $scope so I could test for scope.searchMatch
but I was wondering if this is the only way.
最后,在我的测试中出现 $过滤器
是不确定的太,你怎么注入了吗?我试过,但没有工作:
Finally, on my tests is appears $filter
is undefined too, how do you inject it? I tried this but didn't work:
ctrl = $controller('EmployeeCtrl', { $scope: scope, $filter: $filter });
感谢
更新:
上述注资$器的方法工作得很好。
Update: The method mentioned above to inject $filter works just fine.
推荐答案
我的理解是,在Angularjs,你传递一个范围对象控制器当应用程序启动和控制修改的范围。控制器不再被调用。
My understanding is that, in Angularjs, you pass a scope object to the controller when the application is starting and the controller modify the scope. The controller is not called anymore.
什么是控制器真的做,在Angularjs,正在初始化范围:控制器只运行一次。
如果你明白这一点,你就会意识到,问到控制器像这样的范围:
What a controller is really doing, in Angularjs, is initializing the scope: the controller only runs one time. If you understand this, you realize that asking to the controller for the scope like this:
currentScope = myController.scope;
不会是有道理的。
doesn't makes sense.
(顺便说一句,我不角喜欢的事情之一是,他们已经选择了名字。如果什么是控制器正在做的是初始化范围,那么它是不是一个真正的控制器。有很多的这种在角API)。
(Incidentally, one of the things I don't like in Angular is the names that they have choosen. If what a 'controller' is doing is initializing the scope then it's not really a controller. There are a lot of this in the Angular API).
我认为,对于测试控制器的正确的方式是在茉莉从头开始创建一个新的空白范围的 beforeEach 的条款,并使用控制器对于初始化一个新的空白范围这样的:
I think that the 'proper' way for testing a 'controller' is creating a new blank scope from scratch in a Jasmine beforeEach clause and using the 'controller' for initializing a new blank scope like this::
var ctrl, myScope;
beforeEach(inject(function($controller, $rootScope) {
myScope = $rootScope.$new();
ctrl = $controller('myController', {
$scope: myScope
});
}));
然后再测试新创建范围已预期的属性:
And then testing the new created scope has the expected properties:
it('In the scope, the initial value for a=2', function() {
expect(myScope.a).toBe(2);
});
在换句话说,你不测试控制器;你测试控制器创建范围。
In other words, you don’t test the controller; you test the scope that the controller has created.
所以,你这样做是正确的。
So, you're doing it right.
这篇关于在AngularJs控制器测试$范围与$过滤器的依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!