【问题标题】:how to test controllers created with angular.module().controller() in Angular.js using Mocha如何使用 Mocha 在 Angular.js 中测试使用 angular.module().controller() 创建的控制器
【发布时间】:2012-11-15 04:13:44
【问题描述】:

在这种情况下,我有一个使用 angular.module().controller() 创建的控制器

myModule = angular.module('myApp.controllers', [])
                   .controller('testCtrl', ['$scope', function($scope){
                           $scope.test = 'this is a test';
                    }]);

现在,我需要使用 mocha 来测试我的控制器是否正常工作。在 Angular 中,有一些示例将控制器声明为全局函数(例如 http://docs.angularjs.org/tutorial/step_04),因此它们使用

function PhoneListCtrl() {...}
.....
beforeEach(function() {
   scope = {},
   ctrl = new PhoneListCtrl(scope);
});

it('shod test whatever PhoneListCtrl does ', function() {
   expect(scope.someProp).toBe('whateverValue');
});    

所以问题是:

1) 如何对使用 angular.module().controller() 声明的控制器进行类似的测试

2) 如何使用 Mocha 进行操作

【问题讨论】:

    标签: unit-testing controller angularjs mocha.js


    【解决方案1】:

    AngularJS 提供了一些模拟,可以在测试时为依赖注入提供一些有用的功能。

    示例:

    (在茉莉花中)

    假设我们要从official tutorial 执行第一个测试,并且我们已经定义了一个控制器模块。 (你可以命名模块名称,但我想保持简单)

    var Controllers = angular.module('controllers', []);
    
    Controllers.controller('PhoneListCtrl', ['$scope', function($scope){
        $scope.phones = [{name: "Nexus S", snippet: "Fast..."},
                         {name: "Motorola XOOM...", snippet: "The Next...."},
                         {name: "MOTOROLA XOOM...", snippet: "The Next, Next..."}];
    }]);
    

    然后我们为 out 应用创建一个模块并将其注入我们的控制器模块

    var PhonesApp = angular.module('phoneApp', ['controllers']);
    

    终于可以这样测试了

    describe('phonesApp', function() {
        describe('phoneApp controllers', function() {
            beforeEach(module('controllers'));
            describe('PhoneListCtrl', function() {
                it('should create "phones" model with 3 phones',
                    inject(function($rootScope, $controller) {
    
                    var scope = $rootScope.$new();
                    var ctrl = $controller("PhoneListCtrl", {$scope: scope });
                    expect(scope.phones.length).toBe(3);
                }));
            });
        });
    });
    

    我没在mocha里做过,但我猜过程是相似的。

    Pd:我使用 CoffeeScript 完成了教程,这里是相关位 https://gist.github.com/4163147

    【讨论】:

    【解决方案2】:

    如果您使用的是 mocha,请注意不支持 angular.mock.module 或 angular.mock.inject,除非您已升级到 angular-1.1.1。我在同一条船上,但由于另一个问题我无法升级。

    我想使用 mocha,因为我的服务器端测试是在 mocha 中进行的,而且我更希望双方都拥有相同的测试框架,所以我有点纠结。

    所以,如果你不能使用注入/模块,那么你可以这样尝试:

    var $injector = angular.injector(['your-app-name', 'ng']),
      $controller = $injector.get('$controller'),
      $scope = $injector.get('$rootScope');
    
    describe('my app controllers', function () {
      describe('FooCtrl', function () {
         it('should do something', function () {
            // scope can be any object you want; could be $rootScope from above
            var params = { $scope: { } },
              ctrl = $controller('FooCtrl', params);
            // TODO: test ctrl
         });
      });
    });
    

    【讨论】:

    • 我在 Angular 1.1.2 中仍然遇到同样的问题(angular.mock.inject 不起作用);这种解决方法有帮助;谢谢! (angular.mock.inject 存在并且可以为 mocha 调用,但是 isSpecRunning 会跳过缺少的队列属性,因此它实际上不起作用。)
    • 很好的解决方法,尝试了这个解决方案并且效果很好。但是 1.1.4 版本的 angular.mock 可以和 mocha 一起使用。
    • @Jimchao - 是的,如果你使用 angular-unstable 分支,它们确实支持带有 angular.module.mock 和 angular.mock.inject 的 mocha
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多