我使用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时,出现以下错误 期望undefined被定义。 我有关于上面的问题 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'),则会出现错误,因为它们未定义。
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>
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(); }));and getting following error - Error: [$injector:unpr] http://errors.angularjs.org/undefined/$injector/unpr?p0=%24routeParamsProvider%20%3C-%20%24routeParams
If I add other params in $controller() (i.e. '$routeParams', 'getMailData') Error comes as they are undefined.
最满意答案
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不知道从哪里获取它们并抛出此错误。 $注入器必须知道要为控制器所需的每个参数注入什么。 你的控制器依赖于
$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(); }));如果你没有提供任何这些参数,那么它将尝试从$ injector中获取它,并在未找到时抛出异常。
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) See 1
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.
Regarding your edit:
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: 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 wellSo 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(); }));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.
更多推荐
发布评论