使用Jasmine与AngularJS时出错

r.b*_*waj 3 jasmine angularjs

我使用jasmin用以下代码测试我的AngularJs项目

controllersSpec.js

describe('myApp', function(){

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

    it('should have a mailctrl', function() {
        expect(myApp.mailctrl).toBeDefined();
    });
});
Run Code Online (Sandbox Code Playgroud)

controller.js

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

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

    function ($scope, $routeParams, $rootScope, getMailData, $angularCacheFactory) {
           ##....controller content....##
    }
]);
Run Code Online (Sandbox Code Playgroud)

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();
}));
Run Code Online (Sandbox Code Playgroud)

并获得以下错误 -

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

如果我在$ controller()中添加其他参数(即'$ routeParams','getMailData')错误来自它们未定义.

idu*_*sun 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();
}));
Run Code Online (Sandbox Code Playgroud)

2)见1

3)angular.mock.module用于在测试中将模块注册到进样器.它是一样的module.angular.module用于为您的应用程序创建,注册或检索模块.

关于你的编辑:

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

  • $rootScope:由角度提供
  • $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();
}));
Run Code Online (Sandbox Code Playgroud)

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