当前位置: 首页 > 面试题库 >

在依赖$ filter的AngularJs控制器中测试$ scope

艾宏远
2023-03-14
问题内容

我已经看过一些教程和基本示例,但是我很难为控制器编写单元测试。我已经看到了一些代码片段,它们实例化了控制器并让angular注入了$rootScope对象,该对象又被用来scope为控制器创建一个新对象。但是我不知道为什么ctrl.$scope吗?
未定义

 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但是在我的第一个测试中,我不知道如何在控制器中对 功能变量 进行单元测试:

控制器:

 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:对象#没有方法’searchMatch’

您如何测试该功能?作为一种解决方法,我将方法移至$ scope以便可以进行测试,scope.searchMatch但是我想知道这是否是唯一的方法。

最后,在我的测试中似乎$filter 也是未定义的 ,如何注入呢?我试过了但是没用:

ctrl = $controller('EmployeeCtrl', { $scope: scope, $filter: $filter });

谢谢

更新: 上面提到的注入$ filter的方法效果很好。


问题答案:

我的理解是,在Angularjs中,当应用程序启动并且控制器修改范围时,您将范围对象传递给控制器​​。不再调用控制器。

在Angularjs中,控制器的实际作用是初始化范围:控制器仅运行一次。如果理解了这一点,就会意识到向控制器询问这样的范围:

currentScope = myController.scope;

没有道理。

(顺便说一句,我在Angular中不喜欢的事情之一就是他们选择的名称。如果“控制器”正在做的事情是初始化作用域,那么它并不是真正的控制器。Angular中有很多这样的东西。
API)。

我认为测试“控制器”的“正确”方法是在Jasmine beforeEach 子句中从头开始创建新的空白范围,并使用“控制器”来 初始化
新的空白范围,如下所示:

var ctrl, myScope;

beforeEach(inject(function($controller, $rootScope) {
    myScope = $rootScope.$new();
    ctrl = $controller('myController', {
        $scope: myScope
    });
}));

然后测试新创建的作用域具有预期的属性:

it('In the scope, the initial value for a=2', function() {
            expect(myScope.a).toBe(2);
});

换句话说,您无需测试控制器;您测试控制器已创建的范围。

因此,您做对了。



 类似资料:
  • 我对Symfony 4.2应用程序进行了许多边缘到边缘测试。这里我指的是使用测试客户端进行Web请求,然后对结果进行断言的测试。示例: 在此类测试中,是否有方法更改服务容器中的特定服务? 示例问题:我的服务通过名为的抽象来发出web请求。对于我的测试,我希望使用,这样就不会发出真正的web请求。我如何告诉Symfony使用此双重测试? 令人惊讶的是,在主测试留档中没有关于如何执行此基本测试任务的信

  • 本文向大家介绍AngularJS 单元测试控制器,包括了AngularJS 单元测试控制器的使用技巧和注意事项,需要的朋友参考一下 示例 控制器代码: 考试: 跑!

  • 英文原文:http://emberjs.com/guides/controllers/dependencies-between-controllers/ 有时候,特别是在嵌套资源时,可能需要为两个控制器建立某种联系。以下面的路由为例: 1 2 3 4 5 App.Router.map(function() { this.resource("post", { path: "/posts/:po

  • 英文原文:http://emberjs.com/guides/testing/testing-controllers/ 单元测试方案和计算属性与之前单元测试基础中说明的相同,因为Ember.Controller集成自Ember.Object。 针对控制器的单元测试使用ember-qunit框架的moduleFor来做使这一切变得非常简单。 测试控制器操作 下面给出一个PostsController

  • 问题内容: 我仍然是Angularjs的新手。我想在控制器中动态注入服务(我创建的)的依赖项。 但是,当我对具有依赖项的服务进行编码时,出现此错误: 错误:未知提供程序:$ windowProvider <-$ window <-base64 这是控制器的代码。 此代码有效: 此代码不起作用: 另一个问题是服务与控制器位于同一模块中。如果模块具有依赖项,则无法使用(我的模块配置中具有$ route

  • 问题内容: 我试图在将其他模块作为依赖项的模块中进行单元测试控制器代码的单元化,但是还没有弄清楚如何正确模拟它们。 我正在使用Jasmine Framework,并使用Karma(Testacular)运行测试。 模块代码 规格代码 我得到的错误是Karma是“ no module af.widgets”,因此显然我没有对模块依赖项进行模拟。有什么提示吗? 问题答案: 如果要模拟声明一个或多个服务