使用Jasmine与AngularJS时出错

时间:2014-01-21 08:04:10

标签: angularjs jasmine

我正在使用 jasmin 来测试我的 AngularJs 项目,代码如下

controllersSpec.js

describe('myApp', function(){

    beforeEach(angular.mock.module('myApp'));

    it('should have a mailctrl', function() {
        expect(myApp.mailctrl).toBeDefined();
    });
});

controller.js

var myApp = angular.module('myApp', []);

myApp.controller('mailctrl', ['$scope', '$routeParams', '$rootScope', 'getMailData', '$angularCacheFactory',

    function ($scope, $routeParams, $rootScope, getMailData, $angularCacheFactory) {
           ##....controller content....##
    }
]);

SpecRunner.html

<script type="text/javascript" src="../lib/angular/angular.min.js"></script> <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script> <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script> <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script> <script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script> <script type="text/javascript" src="../test/lib/angular/angular-mocks.js"></script> <script src="../js/controller.js"></script> <script src="../test/unit/controllersSpec.js"></script>

现在,当我在浏览器中打开 Specrunner.html 时,我收到以下错误

预定未定义。
关于上述,我有以下问题 1)我哪里出错了?
2)如何使用控制器的$ rootScope变量?
3) beforeEach(angular.mock.module('myApp')); beforeEach(angular.module('myApp')); beforeEach(模块( '对myApp'));

编辑:

我已将代码修改为

describe('myApp', function(){
    beforeEach(angular.mock.module('myApp'));        
    it('should have a mailctrl', inject(function($rootScope, $controller) {
        var controller = $controller('mailctrl', { $scope: $rootScope.$new(), $rootScope: $rootScope });
        expect(controller).toBeDefined();
}));

并获得以下错误 -

错误:[$ injector:unpr] http://errors.angularjs.org/undefined/ $ injector / unpr?p0 =%24routeParamsProvider%20%3C-%20%24routeParams

如果我在$ controller()中添加其他参数(即'$ routeParams','getMailData')错误是因为它们未定义。

1 个答案:

答案 0 :(得分:7)

1)您尝试将控制器作为模块上的字段进行访问时出错。在测试中,您应该在测试中注入$controller来创建控制器。这意味着您应该编写如下测试:

it('should have a mailctrl', inject(function($rootScope, $controller) {
   var controller = $controller('mainctrl', { $scope: $rootScope.$new(), $rootScope: $rootScope, ...  }) // rest of your dependencies
   expect(controller).toBeDefined();
}));

2)见1

3)angular.mock.module用于将模块注册到 tests 中的注入器。它与module是一回事。 angular.module用于为应用程序创建,注册或检索模块。

关于你的编辑:

您没有提供您的控制器依赖的routeParams和任何其他服务,因此$ injector不知道从何处获取它们并且抛出此错误。 $ injector必须知道控制器所需的每个参数要注入的内容。你的控制器取决于

  • $rootScope:由angular
  • 提供
  • $scope:可以通过$ rootScope。$ new()
  • 创建
  • getMailData:这是您的服务,您必须为此
  • 提供模拟
  • $routeParams:这是有角度的内置结构,但没有专用的模拟,但由于它是一个非常简单的对象,你可以自己提供一个模拟。
  • $angularCacheFactory:这是第三方服务,您必须为此提供模拟

所以最后你应该像这样创建你的控制器:

it('should have a mailctrl', inject(function($rootScope, $controller) {
   var controller = $controller('mainctrl', { 
         $scope: $rootScope.$new(), 
         '$routeParams': {}, // whatever  it needs to be to be able to test your controller
         $rootScope: $rootScope, 
         'getMailData': getMailDataMOCK // this object is created by you in your test code
         '$angularCacheFactory': $angularCacheFactoryMOCK
       }) 
   expect(controller).toBeDefined();
}));

如果你没有提供任何这些参数,那么它将尝试从$ injector获取它,并在未找到时抛出异常。