将 Jasmine 与 AngularJS 一起使用时出错 [英] Getting error while using Jasmine with AngularJS

查看:19
本文介绍了将 Jasmine 与 AngularJS 一起使用时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using jasmin to test my AngularJs project with following code

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(module('myApp'));

Now when I am opening Specrunner.html in browser, I am getting following error

Expected undefined to be defined.
I have following question regarding above

1) Where I am getting wrong ?
2) How can I use $rootScope variable of controller ?
3) Whats the difference in beforeEach(angular.mock.module('myApp')); and beforeEach(angular.module('myApp')); and beforeEach(module('myApp'));



我已将代码修改为

EDIT :

I have modified the code as

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

and getting following error -

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

如果我在 $controller() 中添加其他参数(即 '$routeParams'、'getMailData'),则会出现错误,因为它们未定义.

If I add other params in $controller() (i.e. '$routeParams', 'getMailData') Error comes as they are undefined.

推荐答案

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

1) You are making a mistake by trying to access your controller as a field on a module. in your test you should be injecting $controller into your test to create your controller. What that means is that you should be writing your tests like the following:

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 用于为您的应用程序创建、注册或检索模块.

3) angular.mock.module is used to register your module to the injector in your tests. It is the same thing as module. angular.module is used to create, register or retrieve a module for your application.

关于您的

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

You are not providing routeParams and any other service that your controller depends on so $injector does not know where to get them from and is throwing this error. $injector has to know what to inject for every parameter that is required by your controller. Your controller depends on

  • $rootScope:由 angular 提供
  • $scope:可以通过$rootScope.$new()创建
  • getMailData:这是你的服务,你必须为此提供一个模拟
  • $routeParams:这是 angular 内置结构,但没有专门的 mock,但由于它是一个非常简单的对象,您可以自己为此提供一个 mock.
  • $angularCacheFactory:这是第三方服务,您也必须为此提供模拟
  • $rootScope: provided by angular
  • $scope: can be created by $rootScope.$new()
  • getMailData: This is your service, you have to provide a mock for this
  • $routeParams: This is angular built-in structure but there is not a dedicated mock, but since it is a very simple object you can provide a mock for this yourself.
  • $angularCacheFactory: this is a third party service and you have to provide a mock for this as well

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

So in the end you should be creating your controller like this:

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 获取它,并在找不到时抛出异常.

If you don't provide any of these arguments then it will try to get it from $injector and will throw an exception when not found.

这篇关于将 Jasmine 与 AngularJS 一起使用时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆