My Jasmine unit test is as follows
describe('controllers', function () {
'use strict';
beforeEach(module('myapp.controllers'));
angular.mock.module('myapp.controllers', function ($provide) {
$provide.value('$localStorage', $localStorage);
});
it('should have a creationController', inject(function ($controller, _$rootScope_, localize) {
var scope = _$rootScope_.$new();
var localize = localize;
var myCtrl1 = $controller('creationController', {
$scope: scope,
localize: localize
});
expect(myCtrl1).toBeDefined();
}));
});
When I try to execute the test I'm getting the following error
Error: [$injector:unpr] http://errors.angularjs.org/1.2.20/$injector/unpr?p0=localizeProvider%20%3C-%20localize
There is a dependency called as "localize" being used in the controller. However I'm unable to inject that in to this unit test.
Any idea how I can solve this problem ?
injector look for _componenrToBeInjected_ for injection . If you have a service name localized (Are you sure you have one ?) then for injection use
_ localize_ so your it block should look like this .
it('should have a creationController', inject(function ($controller, _$rootScope_, _localize_) {
var scope = _$rootScope_.$new();
var localize = _localize_;
var myCtrl1 = $controller('creationController', {
$scope: scope,
localize: localize
});
expect(myCtrl1).toBeDefined();
}));
Related
Module is defined as
var $manage = angular.module('manage', [....]);
Controller is defined as
$manage.line.events.controller('eventsController', [..., function(...){
$scope.page = "events";
}]);
My simple unit test case is
describe('Module: manage', function() {
beforeEach(module('manage'));
var scope, ctrl, rootScope;
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('eventsController', {
$scope: scope
});
}));
it("test page", function () {
expect(scope.page).toEqual('events');
});
});
Here, i am getting a error like
Failed to instantiate module ampleManage due to.... manage is not available.
I have integrated angular-mocks.js also. Tried so many possibilities but not working for me.
Basic need is .
Need to access controller/scope in test case.
I am running my tests with karma and phantom, Also I'm using mocha and sinon and tests are getting failed with below error:
EditResourceCategoryDialogTest EditResourceCategoryDialogController "before each" hook: workFn
Error: [$injector:modulerr] http://errors.angularjs.org/1.4.9/$injector/modulerr?p0=resourceofferingsApp&p1=Error%3A%20%5B%24injector%3Amodulerr%5D%20
Sample code:
define(function (require) {
"use strict";
var assert = require('chai').assert;
var sinon = require('sinon');
var angular = require('angular');
var angularMocks = require('angular.mocks');
require('resourceofferings/app');
require('dialog path');
describe('EditResourceCategoryDialogTest', function () {
beforeEach(module('resourceofferingsApp'));
describe('EditResourceCategoryDialogController', function () {
var $scope, ctrl;
//you need to inject dependencies first
beforeEach(inject(function ($rootScope, $injector) {
$scope = $rootScope.$new();
}));
it('initialization test (create mode)', inject(function ($controller) {
ctrl = $controller("EditResourceCategoryDialogController", {
$scope: $scope,
$uibModalInstance: null,
options: {
isEditMode: false
}
});
assert.equal($scope.isEditMode, false);
}));
});
});
});
Its exactly getting failed here:
beforeEach(inject(function ($rootScope, $injector) {
$scope = $rootScope.$new();
}));
Please help me to fix this issue..
Thanks in advance.
Try this ...
describe('controllers', function(){
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new(); // this is what you missed out
controller = $controller('EditResourceCategoryDialogController', {
$scope: scope,
$uibModalInstance: null,
options: {
isEditMode: false
}
});
}));
});
Update: According to Angular ...
A common reason why the module fails to load is that you've forgotten
to include the file with the defined module or that the file couldn't
be loaded.
Are you sure all needed files are loaded?
Unit testing a Directive which uses ngModel that has several function including getAll(). Model gets injected perfectly (when I output it, it shows the accessible getters/setters/etc). I pass it to the element. Do a compile and digest.
Getting the error 'TypeError: Cannot read property 'getAll' of undefined' though.
'console.log('vehiclesModel', vehiclesModel.get('vehicles'));'
Outputs the stubbedData!
'use strict';
describe('Directive: selectBox', function () {
beforeEach(module('sytacApp'));
beforeEach(module('syt.templates'));
var scope,
httpBackend,
$rootScope,
$compile,
element,
vehiclesModel,
stubbedData;
beforeEach(function () {
inject(function ($injector) {
$compile = $injector.get('$compile');
});
});
beforeEach(inject(function (_$rootScope_, _$httpBackend_, _vehiclesModel_, _stubbedData_) {
httpBackend = _$httpBackend_;
$rootScope = _$rootScope_;
vehiclesModel = _vehiclesModel_;
stubbedData = _stubbedData_;
vehiclesModel.set('vehicles', {data: stubbedData.container});
console.log('vehiclesModel', vehiclesModel.get('vehicles'));
}));
it('should process model data accordingly', function () {
var element = angular.element('<select-box identifier="type" selectedidentifier="selectedType" model="vehiclesTypesModel" data-ng-model="vehiclesModel"></select-box>');
element = $compile(element)(scope);
scope.$digest();
//......
});
});
Question. Am I overlooking something?
had to put ´vehiclesModel´ on ´scope scope.vehiclesModel´ before ´$compile´
I have been doing angularJS for a while now (without tests) but I want to do it properly! I have a controller defined like so
(function () {
'use strict';
angular.module('app')
.controller('CarehomeListCtrl', ['$scope', 'carehomesDataService', carehomeListCtrl]);
function carehomeListCtrl($scope, carehomesDataService) {
var vm = this;
vm.carehomeCollection = [];
vm.activate = activate;
function activate() {
vm.carehomeCollection = carehomesDataService.getAllCarehomes();
}
activate();
}
})();
and then my spec
describe("Carehomes tests", function () {
var $scopeConstructor, $controllerConstructor;
beforeEach(module('app'));
beforeEach(inject(function ($controller, $rootScope) {
$controllerConstructor = $controller;
$scopeConstructor = $rootScope;
}));
describe("CarehomeListCtrl", function () {
var ctrl, dataService, scope;
function createController() {
return $controllerConstructor('CarehomeListCtrl', {
$scope: scope,
carehomesDataService: dataService
});
}
beforeEach(inject(function ($injector) {
scope = $scopeConstructor.$new();
dataService =$injector.get('carehomesDataService') ;
}));
it("should have a carehomesCollection array", function () {
ctrl = createController();
expect(ctrl.carehomesCollection).not.toBeNull();
});
it("should have 3 items in carehomesCollection array when load is called", function () {
ctrl = createController();
expect(ctrl.carehomeCollection.length).toBe(3);
});
});
});
The problem here is that the call to instantiate my controller fails with error whenever I call it with any arguments whether an empty object {} or just $scope : scope} so I know the problem is not carehomesDataService.
Result StackTrace: Error: [ng:areq] Argument 'CarehomeListCtrl' is not
a function, got undefined
http://errors.angularjs.org/1.2.26/ng/areq?p0=CarehomeListCtrl&p1=not%20a%20function%2C%20got%20undefined
However, if I instantiate that controller like this $controllerConstructor('CarehomeListCtrl'); without arguments, it gets instantiated. I'm stumped!
carehomesDataService is a custom service I have written but it's own tests pass and it is correctly injected into the controller in the application.
Any help would be massively appreciated.
Note: I do not quite agree with defining properties on the controller as the view model instead of on $scope but I am following Jesse Liberty's pluralsight course and that's how he does it....plus injecting scope isn't quite working right now which is annoying. Thanks in advance.
I get the following error: TypeError: undefined is not a function
The problem is that the common is module and a factory and the problem is on my line
var ctrl = $controllerConstructor("resetPasswordSentScreen", { $scope: scope, common: common});
Here is the full test:
describe('resetPasswordSentScreen', function () {
var scope, $controllerConstructor;
beforeEach(module('common', 'app'));
beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope.$new();
$controllerConstructor = $controller;
}));
it('it should navigate to the correct url when backToLogin is called ', function (common) {
var ctrl = $controllerConstructor("resetPasswordSentScreen", { $scope: scope, common: common });
var mocklocation = sinon.stub({ url: function () {}});
expect(scope.backToLogin()).toBe(mocklocation.url);
});
});
That is not the problem, the problem is that you can't inject stuff into your functions like you do in your code. To inject you need to call inject as you did in the beforeEach. So, if you want to inject that factory, you need this:
it("message", inject(function(common) {
...
}));
There is how you inject. That should work.