【问题标题】:Getting error while using Jasmine with AngularJS将 Jasmine 与 AngularJS 一起使用时出错
【发布时间】:2014-02-10 16:58:10
【问题描述】:

我正在使用 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 时,出现以下错误

Expected undefined to be defined.
我对上述问题有以下疑问

1) 我哪里出错了?
2) 如何使用控制器的 $rootScope 变量?
3) beforeEach(angular.mock.module('myApp'));beforeEach(angular.module('myApp')); 有什么区别>beforeEach(module('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'),则会出现错误,因为它们未定义。

【问题讨论】:

    标签: angularjs jasmine


    【解决方案1】:

    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 用于在您的测试 中将您的模块注册到注入器。它与module 相同。 angular.module 用于为您的应用程序创建、注册或检索模块。

    关于您的编辑:

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

    • $rootScope:由角提供
    • $scope: 可以通过 $rootScope.$new() 创建
    • getMailData:这是你的服务,你必须为此提供一个模拟
    • $routeParams:这是 angular 内置结构,但没有专门的 mock,但由于它是一个非常简单的对象,您可以自己提供一个 mock。
    • $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 获取它,并在找不到时抛出异常。

    【讨论】:

    猜你喜欢
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 2021-12-06
    相关资源
    最近更新 更多