将 Jasmine 与 AngularJS 一起使用时出错 [英] Getting error while using Jasmine with 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屋!