Getting error in controller while unit testing using karma jasmine - angularjs

I'm getting this error while I'm running unit test using Karma-Jasmine
ReferenceError: myModule is not defined
My sample test case is as follows..
describe("Unit Testing", function() {
beforeEach(angular.mock.module('myModule.common'));
var scope, ngTableParams, filter ,testTableParam;
it('should have a commonController controller', function () {
expect(myModule .common.controller('commonController ', function (commonController ) {
$scope:scope;
ngTableParams:ngTableParams;
$filter: filter;
tableParams: testTableParam
}
)).toBeDefined();
});});
I have injected the module name as myModule.common.
Can you please suggest a solution?

Try following code snippet it might help
describe('testing myModule.common', function() {
var $rootScope, $scope, $filter, $controller, ngTableParams, testTableParam;
beforeEach(module('myModule.common'));
beforeEach(function() {
inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
$filter = $injector.get('$filter');
testTableParam = $injector.get('testTableParam');
ngTableParams = $injector.get('ngTableParams');
$controller = $injector.get('$controller')('commonController ', {
$scope: $scope
});
});
});
it('testing commonController ', function() {
expect('commonController ').toBeDefined();
});
});
It will solve your problem

Related

"before each" hook: workFn error

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?

How to Unit Test Angular with Jasmine Controller inside a Directive

So I am trying to learn how to unit test with Jasmine with Angular. I have got a number of unit tests working but this one has stumped me. I took out the alerts array in my test you can make it any array.. But how to mock this and getting this to work has really stumped me. I would think that the object would exist.
(function () {
var app = angular.module("TabDirectives", ["Communication"]);
app.directive("sentAlerts", ["DirectiveProvider", "DataProvider", function (DirectiveProvider, DataProvider) {
var dir = DirectiveProvider("SentAlerts");
dir.controller = function () {
var ctrl = this;
DataProvider("AlertsByDate").then(function (Result) {
ctrl.AlertList = Result.data;
});
};
dir.controllerAs = "Alerts"
return dir;
}]);
})()
I have a test that looks like
describe("Tab Directive Unit Tests", function () {
var controller;
describe("Tab Directive Default Values", function () {
beforeEach(inject(function ($rootScope, $compile) {
element = angular.element("<sent-alerts></sent-alerts>");
$compile(element)($rootScope.$new());
$rootScope.$digest();
controller = element.controller;
}));
it("Ctrl should be this", function () {
expect(controller.ctrl).toBe(controller.this);
});
it("AlertList should have Alerts", function () {
expect(controller.ctrl.AlertList).toBe(alerts);
});
});
});
The error I'm getting looks like
TypeError: Cannot read property 'AlertList' of undefined
You have to initialize and inject your controller as well. Something like this:
var $controller;
var $rootScope;
var scope;
var controller;
beforeEach(inject(function (_$controller_, _$rootScope_) {
$controller = _$controller_;
$rootScope = _$rootScope_;
scope = $rootScope.$new();
controller = $controller('ScopeController', { '$scope': scope });
}));

How can I resolve a $q.all in my controller in a Karma unit test?

My controller has:
switchUserAccount: function() {
$scope.model.currentMode = 'user';
console.log(ipCookie('currentPatientId'));
$q.all([facilityCache.getFacility(), facilityGroupCache.getGroupList(), languageCache.getLanguageList(), genderCache.getGenderList(), raceCache.getRaceList(), dosingCache.getDosingOptions()])
.then(function(){
console.log('back from then');
cache.set('ui', 'adminPage', '');
cache.set('ui', 'schedulePage', 'patients');
if(ipCookie('currentPatientId')) {
$location.path('/patient/view/' + ipCookie('currentPatientId'));
} else {
$location.path('/patients');
}
});
},
and my test is
describe('MainHeaderController', function() {
var scope, $rootScope, $locationMock, $httpBackend;
beforeEach(function() {
module('mapApp');
return inject(function($injector) {
var $controller, $q, ipCookieMock;
$rootScope = $injector.get('$rootScope');
$controller = $injector.get('$controller');
$httpBackend = $injector.get('$httpBackend');
$q = $injector.get('$q');
$locationMock = jasmine.createSpyObj('$location', ['path'])
ipCookieMock = function() {
return 123;
}
scope = $rootScope.$new()
$controller('MainHeaderController', {
$scope: scope,
$location: $locationMock,
$q: $q,
ipCookie: ipCookieMock
});
$httpBackend.whenGET('/rpc/session').respond(200);
$httpBackend.whenPOST('/rpc').respond(200);
return scope.$digest();
});
});
it('should redirect to a patient view if a cookie is set', function($rootScope) {
scope.switchUserAccount();
// $rootScope.$apply();
expect($locationMock.path).toHaveBeenCalledWith('/patient/view/123');
});
});
So what I expect to happen is for $location.path to be called with /patient/view/123. Instead, what I get is
Expected spy $location.path to have been called with [ '/patient/view/123' ] but actual calls were [ ].
If I uncomment out the $rootScope.$apply(), I get
TypeError: 'undefined' is not a function (evaluating '$rootScope.$apply()')
So how can I trigged the $q.all in my controller so that the test can pass properly?
Thanks!
You're hiding the $rootScope variable of your test suite by declaring it as an argument of your test function. That's why it's undefined: jasmine calls the test functions withput any argument.
Replace
it('should redirect to a patient view if a cookie is set', function($rootScope) {
by
it('should redirect to a patient view if a cookie is set', function() {

AngularJS - Unit Test - Test Controller With Custom Services

I have been searching for a couple of hours now for a solution for this but I just can't make it work.
I have a Controller defined as:
(function () {
'use strict';
angular.module('spaSkeleton.parCCP')
.controller('ParCCPCtrl', function ($scope, $mdToast, AnosLetivosService, UnidadesOrganicasService, CursosService, RelatoriosService, PareceresService) {
//my code
and I want to test this controller, but i have all this Services that I have to inject.
One of the Services looks like this:
var app = angular.module('sigq.anosLetivos', []);
app.service('AnosLetivosService', function (Restangular) {
this.getAnosLetivos = function () {
return Restangular.all("anos-letivos").getList({"sort": "ano_inicio"});
};
});
and in my test file I have this:
describe('Parecer Controllers', function(){
beforeEach(module('spaSkeleton.parCCP'));
beforeEach(function() {
module('namespace.anosLetivos');
module('namespace.unidadesOrganicas');
module('namespace.cursos');
module('namespace.relatorios');
module('namespace.pareceres');
module('namespace.landingPage');
});
describe('Parecer Ctrl', function(){
var scope, ctrl, $httpBackend;
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET(...).respond(...);
scope = $rootScope.$new();
ctrl = $controller('ParCtrl', {$scope: scope});
}));
});
});
I would like some help on how to inject these services into the controller so i can test it. I already tried a lot of stuff.
https://docs.angularjs.org/tutorial/step_11 this looks easy but does not work, he doesn't even inject stuff or does he? I know in the tutorial works but I don't know how and why and I can't make it work on my project.
Any help is welcome :D
so I solved my problem, the problem was that the services had a module that i had to inject in the test that i wasn't seeing.
describe('Parecer Controllers', function(){
beforeEach(module('spaSkeleton.parCCP'));
beforeEach(function() {
module('sigq.anosLetivos');
module('sigq.unidadesOrganicas');
module('sigq.cursos');
module('sigq.relatorios');
module('sigq.pareceres');
module('restangular');
module('ngMaterial');
});
var $scope;
var $controller;
var $mdToast, AnosLetivosService, UnidadesOrganicasService, CursosService, RelatoriosService, PareceresService, Restangular;
beforeEach(inject(function(_$controller_, _$q_, _AnosLetivosService_, _UnidadesOrganicasService_, _CursosService_,
_RelatoriosService_, _PareceresService_, _Restangular_, _$mdToast_) {
$scope = {};
$mdToast = _$mdToast_;
Restangular = _Restangular_;
$controller = _$controller_;
AnosLetivosService = _AnosLetivosService_;
UnidadesOrganicasService = _UnidadesOrganicasService_;
CursosService = _CursosService_;
RelatoriosService = _RelatoriosService_;
PareceresService = _PareceresService_;
$controller('ParCCPCtrl',
{
'$scope': $scope,
'AnosLetivosService': AnosLetivosService,
'UnidadesOrganicasService': UnidadesOrganicasService,
'CursosService': CursosService,
'RelatoriosService': RelatoriosService,
'PareceresService': PareceresService,
'$mdToast': $mdToast
});
}));
it('should make Blog menu item active.', function() {
expect(1).toEqual(1);
});
});
so i need all this code to test my controller xD

AngularJS - Unit test for http get to JSON file

I am trying to write a unit test to test a simple factory that performs a http.get to retrieve a JSON file.
The factory is called within my controller.
Here's a plunker showing my http.get: http://plnkr.co/edit/xg9T5H1Kreo4lwxzRQem?p=preview
Ctrl:
app.controller('MainCtrl', function($scope, $http, factoryGetJSONFile) {
factoryGetJSONFile.getMyData(function(data) {
$scope.Addresses = data.Addresses.AddressList;
$scope.People = data.Names.People;
});
});
Factory:
app.factory('factoryGetJSONFile', function($http) {
return {
getMyData: function(done) {
$http.get('data.json')
.success(function(data) {
done(data);
})
.error(function(error) {
alert('An error occured whilst trying to retrieve your data');
});
}
}
});
Test:
// ---SPECS-------------------------
describe('with httpBackend', function () {
var app;
beforeEach(function () {
app = angular.mock.module('plunker')
});
describe('MyCtrl', function () {
var scope, ctrl, theService, httpMock;
beforeEach(inject(function ($controller, $rootScope, factoryGetJSONFile, $httpBackend) {
scope = $rootScope.$new(),
ctrl = $controller('MyCtrl', {
$scope: scope,
factoryGetJSONFile: theService,
$httpBackend: httpMock
});
}));
it("should make a GET call to data.json", function () {
console.log("********** SERVICE ***********");
httpMock.expectGET("data.json").respond("Response found!");
//expect(factoryGetJSONFile.getMyData()).toBeDefined();
httpMock.flush();
});
})
});
Error:
TypeError: 'undefined' is not an object (evaluating 'httpMock.expectGET')
You should assign $httpBackend to httpMock in beforeEach like this:
beforeEach(inject(function ($controller, $rootScope, factoryGetJSONFile, $httpBackend) {
httpMock = $httpBackend;
scope = $rootScope.$new();
ctrl = $controller('MyCtrl', {
$scope: scope,
factoryGetJSONFile: factoryGetJSONFile,
$httpBackend: httpMock
});
}));

Resources