在依赖于 $filter 的 AngularJs 控制器中测试 $scope [英] Testing $scope in AngularJs controller with dependency on $filter

查看:18
本文介绍了在依赖于 $filter 的 AngularJs 控制器中测试 $scope的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了一些教程和基本示例,但是我很难为我的控制器编写单元测试.我已经看到代码片段实例化控制器并让 angular 注入 $rootScope 对象,该对象又用于为控制器创建一个新的 scope 对象.但我不明白为什么 ctrl.$scope?未定义:

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!       
    }));
});

我最终使用了 scope 变量而不是 ctrl.$scope 但是在我的第一次测试中我无法弄清楚如何对 进行单元测试控制器内部的函数变量:

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);
});

这是我得到的

TypeError: Object # 没有方法 'searchMatch'

TypeError: Object # has no method 'searchMatch'

您如何测试该功能?作为一种解决方法,我将我的方法移至 $scope 以便我可以测试 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.

最后,在我的测试中出现$filter 未定义,你如何注入它?我试过了,但没有用:

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 });

谢谢

更新:上面提到的注入 $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;

没有意义.

(顺便说一句,我不喜欢 Angular 中的一件事是他们选择的名称.如果控制器"正在做的是初始化范围,那么它并不是真正的控制器.有很多这样的在 Angular 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).

我认为测试控制器"的正确"方法是在 Jasmine 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.

所以,你做对了.

这篇关于在依赖于 $filter 的 AngularJs 控制器中测试 $scope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆