Ionic - Argument is not a function, got undefined when testing with karma - angularjs

I'm creating an Ionic application and I would like test it using Karma, however I'm getting this error when I run Karma:
Error: [ng:areq] Argument 'SelecaoLocalizacaoController' is not a function, got undefined
I've checked if the controller file was added in karma conf, but it is:
module.exports = function (config) {
config.set({
basePath: '../',
frameworks: ['jasmine'],
files: [
'www/lib/ionic/js/ionic.bundle.js',
'www/lib/ngCordova/dist/ng-cordova-mocks.js',
'www/lib/angular-mocks/angular-mocks.js',
'www/js/app.js',
'www/js/app/**/*.js',
'www/js/components/**/*.{js,html}',
'test/**/!(karma.conf).js'
],
exclude: [],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: false,
browserDisconnectTimeout: 10000, // default 2000
browserDisconnectTolerance: 1, // default 0
browserNoActivityTimeout: 4 * 60 * 1000 //default 10000
})
};
This is the spec I'm trying run:
'use strict';
describe('Controller Tests', function () {
var $scope, $rootScope, LocalizacaoService, EstadosComEstabelecimentos;
var estadosRetornados = [{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}];
var createController;
describe('SelecaoLocalizacaoController aff', function () {
beforeEach(inject(function ($injector) {
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();
LocalizacaoService = {
getCidadeAtual: function (success, error) {
success({
idEstado: 56,
idCidade: 651
});
}
};
EstadosComEstabelecimentos = {
get: function () {
return {
then: function (callback) {
return callback({
data: estadosRetornados
});
}
}
}
};
var ionicModal = {
fromTemplateUrl: function () {
return {
then: function () {
}
};
}
};
var locals = {
'$scope': $scope,
'$rootScope': $rootScope,
'$ionicModal': ionicModal,
'LocalizacaoService': LocalizacaoService,
'EstadosComEstabelecimentos': EstadosComEstabelecimentos
};
createController = function () {
$injector.get('$controller')("SelecaoLocalizacaoController", locals);
};
createController();
}));
describe('inicialização', function () {
it('deve carregar todos os estados com estabelecimentos ativos cadastrados', function () {
expect($scope.estados).not.toBe(undefined);
expect($scope.estados.length).toBe(5);
expect($scope.estados[0]).toEqual({id: 1});
expect($scope.estados[1]).toEqual({id: 2});
expect($scope.estados[2]).toEqual({id: 3});
expect($scope.estados[3]).toEqual({id: 4});
expect($scope.estados[4]).toEqual({id: 5});
});
it('deve selecionar estado e cidade a partir das coordenadas do GPS', function () {
expect($scope.posicao.idEstado).toBe(56);
expect($scope.posicao.idCidade).toBe(651);
expect($scope.exibirMensagemNaoEncontrado).toBeFalsy();
});
});
});
});
Finally, this is the controller I'm testing:
'use strict';
angular.module('cervejeirosApp')
.controller('SelecaoLocalizacaoController', function ($scope, $ionicModal, EstadosComEstabelecimentos, LocalizacaoService) {
$scope.loadAll = function () {
EstadosComEstabelecimentos.get()
.then(function (result) {
$scope.estados = result.data;
});
LocalizacaoService.getCidadeAtual(function (result) {
if (angular.isDefined(result) && result != null)
$scope.posicao = result;
else {
$scope.posicao = {idEstado: null, idCidade: null};
$scope.exibirMensagemNaoEncontrado = true;
}
});
$ionicModal.fromTemplateUrl('js/app/localizacao/modal-selecao-estado.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modalEstado = modal;
});
};
$scope.selecionarEstado=function(){
$scope.modalEstado.show();
};
$scope.selecionouEstado=function(estado){
$scope.posicao.idEstado=estado.id;
$scope.modalEstado.hide();
};
$scope.loadAll();
});

Related

Jasmine unit test controller

I need to check two thing here:
The response length. specified the mock data as [{ name: 'John', id: 1 }, { name: 'Josh', id: 2 }] so the response length should be 2. it is failing this test always getting the length as 1.
The response data should be equal. ie. expect(IndexSummaryService.getIndexSummaryQueues).toEqual([{ name: 'John', id: 1 }, { name: 'Josh', id: 2 }]);
The test is failing with Message: Expected Function to equal [object({ name:'john', id:1}), object({ name:'josh', id:2}) ]
My service is bit different which takes api as parameter which is the URL.
Please suggest how to make these unit test working.
This is the service code
app.service("IndexSummaryService", ['$http', function ($http) {
this.getIndexSummaryQueues = function (api) {
return $http.get(api, { cache: false });
};
}]);
This is the controller
$scope.loadRecords = function (api) {
$scope.loading = true;
var GetIndexSummaryQueue = IndexSummaryService.getIndexSummaryQueues(api);
GetIndexSummaryQueue.then(function (response) {
$scope.Queues = response.data;
}, function (error) {
if (error.status == 500) {
$scope.errorStatus = "Error " + error.status;
$scope.errorMsg = error.data.message;
}
else {
$scope.errorStatus = "Error " + error.status;
$scope.errorMsg = GlobalConstants.errormessage;
}
$scope.errorpage = true;
$scope.success = false;
console.log("Status Data : " + error.data.message);
console.log("Status Error : " + error.status);
}).then(function () {
$scope.loading = false;
});
}
I have written unit test in jasmine below is the jasmine code.
describe("ISummary ->", function () {
beforeEach(function () {
module("ApplicationModule");
});
var $httpBackend;
var scope, createController;
beforeEach(inject(function ($rootScope, _$httpBackend_, $controller) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
createController = function () {
return $controller('IndexingSummaryController', {
$scope: scope
});
};
$httpBackend.when("GET", "https://domain.com/captivaapi/api/capturestats/pldindexingSummary")
.respond([{ name: 'John', id: 1 }, { name: 'Josh', id: 2 }]);
}));
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe("Service->", function () {
it("can load topics", inject(function (IndexSummaryService) {
$httpBackend.expectGET("https://domain.com/captivaapi/api/capturestats/pldindexingSummary");
IndexSummaryService.getIndexSummaryQueues('https://domain/captivaapi/api/capturestats/pldindexingSummary');
$httpBackend.flush();
expect(IndexSummaryService.getIndexSummaryQueues.length).toBeGreaterThan(0);
expect(IndexSummaryService.getIndexSummaryQueues.length).toEqual(2);
expect(IndexSummaryService.getIndexSummaryQueues).toEqual([{ name: 'John', id: 1 }, { name: 'Josh', id: 2 }]);
}));
});
You're not testing the response of the promise, try the below (might not be exact as it's been a while since I used Angular, but basically make your assertions in a then block, once the promise has resolved).
describe("Service->", function () {
it("can load topics", inject(function (IndexSummaryService) {
$httpBackend.expectGET("https://domain.com/captivaapi/api/capturestats/pldindexingSummary");
IndexSummaryService.getIndexSummaryQueues('https://domain/captivaapi/api/capturestats/pldindexingSummary').then(function(res) {
expect(res.length).toBeGreaterThan(0);
expect(res.length).toEqual(2);
expect(res).toEqual([{ name: 'John', id: 1 }, { name: 'Josh', id: 2 }]);
});
$httpBackend.flush();
}));
});

Angular Karma/Jasmine Unit Test not working

I'm trying to write unit tests for my new Angular App and have troubles. Below is my controller.
'use strict';
angular.module('nileLeApp')
.controller('RegisterController', function ($scope, $translate, $timeout, vcRecaptchaService, Auth, Country, Timezone, RecaptchaService) {
$scope.success = null;
$scope.error = null;
$scope.doNotMatch = null;
$scope.errorUserExists = null;
$scope.registerAccount = {};
$timeout(function () {
angular.element('[ng-model="registerAccount.email"]').focus();
});
$scope.loadCountries = function () {
Country.getCountries()
.then(function (result) {
$scope.countries = result.data;
});
};
$scope.loadTimezones = function () {
Timezone.getTimezones()
.then(function (result) {
$scope.timezones = result.data;
});
};
// ============ Recaptcha specific code START ===============
$scope.recaptcha = {};
$scope.recaptcha.recaptchaResponse = null;
$scope.recaptchaWidgetId = null;
$scope.setResponse = function (response) {
$scope.recaptcha.recaptchaResponse = response;
$scope.recaptchaMissing = false;
};
$scope.setWidgetId = function (widgetId) {
$scope.recaptchaWidgetId = widgetId;
};
$scope.cbExpiration = function () {
$scope.recaptcha.recaptchaResponse = null;
};
// ============ Recaptcha specific code END ===============
$scope.createAccount = function () {
Auth.createAccount($scope.registerAccount).then(function (response) {
$scope.success = true;
}).catch(function (response) {
$scope.success = false;
});
}
$scope.register = function () {
$scope.recaptchaMissing = false;
$scope.recaptchaInvalid = false;
if ($scope.recaptcha.recaptchaResponse != null) {
RecaptchaService.verify($scope.recaptcha).$promise
.then(function (response) {
if (response.data) {
$scope.createAccount();
} else {
$scope.recaptchaInvalid = true;
vcRecaptchaService.reload($scope.recaptchaWidgetId); // Reload captcha
}
}).catch(function (response) {
});
} else {
$scope.recaptchaMissing = true;
}
};
$scope.loadCountries();
$scope.loadTimezones();
});
Below is the test I'm trying.
'use strict';
describe('Register Controllers Tests', function () {
describe('RegisterController', function () {
// actual implementations
var $scope;
var $q;
// mocks
var MockTimeout;
var MockTranslate;
var MockAuth;
var MockCountry;
var MockTimezone;
// local utility function
var createController;
beforeEach(inject(function ($injector) {
$q = $injector.get('$q');
$scope = $injector.get('$rootScope').$new();
MockTimeout = jasmine.createSpy('MockTimeout');
MockAuth = jasmine.createSpyObj('MockAuth', ['createAccount']);
MockCountry = jasmine.createSpyObj('MockCountry', ['getCountries']);
MockTimezone = jasmine.createSpyObj('MockTimezone', ['getTimezones']);
MockTranslate = jasmine.createSpyObj('MockTranslate', ['use']);
var locals = {
'$scope': $scope,
'$translate': MockTranslate,
'$timeout': MockTimeout,
'Auth': MockAuth,
'Country': MockCountry,
'Timezone': MockTimezone
};
createController = function () {
$injector.get('$controller')('RegisterController', locals);
};
}));
it('should load countries on page load', function () {
var mockCountryResponse = [{
'countryId': 1,
'alpha2Code': "AF",
'countryName': "Afghanistan"
}];
MockCountry.getCountries.and.returnValue($q.resolve(mockCountryResponse));
MockTimezone.getTimezones.and.returnValue($q.resolve());
MockAuth.createAccount.and.returnValue($q.resolve());
// given
createController();
$scope.$apply($scope.loadCountries);
expect($scope.countries).toEqual(mockCountryResponse);
});
});
The above expectation doesn't work because $scope.countries is undefined. Following is the error message.
TypeError: 'undefined' is not an object (evaluating 'result.data')
Also, I see the test getting called twice for some strange reason. Below is my Karma configuration file.
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function (config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '../../',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
// bower:js
'main/webapp/bower_components/es5-shim/es5-shim.js',
'main/webapp/bower_components/jquery/dist/jquery.js',
'main/webapp/bower_components/angular/angular.js',
'main/webapp/bower_components/angular-animate/angular-animate.js',
'main/webapp/bower_components/angular-aria/angular-aria.js',
'main/webapp/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'main/webapp/bower_components/bootstrap/dist/js/bootstrap.js',
'main/webapp/bower_components/angular-bootstrap-nav-tree/dist/abn_tree_directive.js',
'main/webapp/bower_components/angular-file-upload/angular-file-upload.js',
'main/webapp/bower_components/angular-messages/angular-messages.js',
'main/webapp/bower_components/skycons/skycons.js',
'main/webapp/bower_components/angular-skycons/angular-skycons.js',
'main/webapp/bower_components/angular-smart-table/dist/smart-table.min.js',
'main/webapp/bower_components/angular-touch/angular-touch.js',
'main/webapp/bower_components/angular-cache-buster/angular-cache-buster.js',
'main/webapp/bower_components/angular-cookies/angular-cookies.js',
'main/webapp/bower_components/angular-dynamic-locale/src/tmhDynamicLocale.js',
'main/webapp/bower_components/angular-local-storage/dist/angular-local-storage.js',
'main/webapp/bower_components/angular-loading-bar/build/loading-bar.js',
'main/webapp/bower_components/angular-resource/angular-resource.js',
'main/webapp/bower_components/angular-sanitize/angular-sanitize.js',
'main/webapp/bower_components/angular-translate/angular-translate.js',
'main/webapp/bower_components/messageformat/messageformat.js',
'main/webapp/bower_components/angular-translate-interpolation-messageformat/angular-translate-interpolation-messageformat.js',
'main/webapp/bower_components/angular-translate-loader-partial/angular-translate-loader-partial.js',
'main/webapp/bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'main/webapp/bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.js',
'main/webapp/bower_components/angular-translate-storage-local/angular-translate-storage-local.js',
'main/webapp/bower_components/angular-ui-router/release/angular-ui-router.js',
'main/webapp/bower_components/moment/moment.js',
'main/webapp/bower_components/fullcalendar/dist/fullcalendar.js',
'main/webapp/bower_components/angular-ui-calendar/src/calendar.js',
'main/webapp/bower_components/angular-ui-grid/ui-grid.js',
'main/webapp/bower_components/angular-ui-select/dist/select.js',
'main/webapp/bower_components/angular-ui-utils/ui-utils.js',
'main/webapp/bower_components/angular-xeditable/dist/js/xeditable.js',
'main/webapp/bower_components/angularjs-toaster/toaster.js',
'main/webapp/bower_components/angular-strap/dist/angular-strap.js',
'main/webapp/bower_components/angular-strap/dist/angular-strap.tpl.js',
'main/webapp/bower_components/angular-recaptcha/release/angular-recaptcha.js',
'main/webapp/bower_components/bootstrap-daterangepicker/daterangepicker.js',
'main/webapp/bower_components/bootstrap-filestyle/src/bootstrap-filestyle.js',
'main/webapp/bower_components/bootstrap-slider/bootstrap-slider.js',
'main/webapp/bower_components/bootstrap-tagsinput/dist/bootstrap-tagsinput.js',
'main/webapp/bower_components/bootstrap-wysiwyg/bootstrap-wysiwyg.js',
'main/webapp/bower_components/bower-jvectormap/jquery-jvectormap-1.2.2.min.js',
'main/webapp/bower_components/datatables/media/js/jquery.dataTables.js',
'main/webapp/bower_components/flot/jquery.flot.js',
'main/webapp/bower_components/flot-spline/js/jquery.flot.spline.js',
'main/webapp/bower_components/flot.tooltip/js/jquery.flot.tooltip.js',
'main/webapp/bower_components/footable/js/footable.js',
'main/webapp/bower_components/html5sortable/jquery.sortable.js',
'main/webapp/bower_components/json3/lib/json3.js',
'main/webapp/bower_components/ng-grid/build/ng-grid.js',
'main/webapp/bower_components/intl-tel-input/build/js/intlTelInput.min.js',
'main/webapp/bower_components/intl-tel-input/lib/libphonenumber/build/utils.js',
'main/webapp/bower_components/ng-intl-tel-input/dist/ng-intl-tel-input.js',
'main/webapp/bower_components/ngImgCrop/compile/minified/ng-img-crop.js',
'main/webapp/bower_components/ngstorage/ngStorage.js',
'main/webapp/bower_components/ng-file-upload/ng-file-upload.js',
'main/webapp/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js',
'main/webapp/bower_components/oclazyload/dist/ocLazyLoad.min.js',
'main/webapp/bower_components/screenfull/dist/screenfull.js',
'main/webapp/bower_components/slimscroll/jquery.slimscroll.min.js',
'main/webapp/bower_components/textAngular/dist/textAngular.min.js',
'main/webapp/bower_components/venturocket-angular-slider/build/angular-slider.js',
'main/webapp/bower_components/videogular/videogular.js',
'main/webapp/bower_components/videogular-buffering/buffering.js',
'main/webapp/bower_components/videogular-controls/controls.js',
'main/webapp/bower_components/videogular-ima-ads/ima-ads.js',
'main/webapp/bower_components/videogular-overlay-play/overlay-play.js',
'main/webapp/bower_components/videogular-poster/poster.js',
'main/webapp/bower_components/waves/dist/waves.min.js',
'main/webapp/bower_components/angular-mocks/angular-mocks.js',
// endbower
'main/webapp/scripts/app/app.js',
'main/webapp/scripts/app/**/*.+(js|html)',
'main/webapp/scripts/components/**/*.+(js|html)',
'test/javascript/spec/helpers/module.js',
'test/javascript/spec/helpers/httpBackend.js',
'test/javascript/**/!(karma.conf|protractor.conf).js'
],
// list of files / patterns to exclude
exclude: ['test/javascript/e2e/**'],
preprocessors: {
'./main/webapp/scripts/**/*.js': ['coverage'],
'**/*.html': ['ng-html2js']
},
reporters: ['dots', 'jenkins', 'coverage', 'progress'],
jenkinsReporter: {
outputFile: '../build/test-results/karma/TESTS-results.xml'
},
coverageReporter: {
dir: '../build/test-results/coverage',
reporters: [
{type: 'lcov', subdir: 'report-lcov'}
]
},
// web server port
port: 9876,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true,
// to avoid DISCONNECTED messages when connecting to slow virtual machines
browserDisconnectTimeout : 10000, // default 2000
browserDisconnectTolerance : 1, // default 0
browserNoActivityTimeout : 4*60*1000 //default 10000
});
};
I'm stuck on writing unit test for last couple days as I find them quite confusing and not simple like in Java. Will appreciate any help.
The above expectation doesn't work because $scope.countries is undefined
^^ That's not true. It's not that $scope.countries is undefined, it's that result is undefined, and it's not the result you're trying to assign to $scope.countries, it's the one relating to $scope.timezones
I think this is your problem here:
MockTimezone.getTimezones.and.returnValue($q.resolve());
You're implicitly passing undefined into that resolve() function, and THAT'S throwing an error when you instantiate your controller.
It's throwing that error because you've got this line at the end of your controller:
$scope.loadTimezones();
It's for this reason that I stopped initializing controllers within themselves. Now I do it using ng-init, initiated from the HTML. If you make the same change as I did you won't encounter issues like this again in the future.

how to inject module dependencies in angular test unit with karma

it's the first time that i use angular application using generator and units tests with karma.
i wanna create some angularjs unit test for my app based on bower, gulp, karma...
this is my controller :
(function() {
'use strict';
angular.module('order', ['common'])
.controller('OrderVehiculesController', function (drivers,Logger) {
var self = this;
this.orderForm = {
id: '',
txt: ''
};
this.msgCtrlError = {
id: ''
};
var logger = Logger.getInstance('OrderVehiculesController');
logger.log(self);
this.getOrder = function (name) {
// A modifier car il serait plus judicieux d'avoir un model d'object et de pouvoir les réinitialiser avec une function
self.msgCtrlError.id = '';
self.msgCtrlError.txt = '';
drivers
.getOrder(name)
.then(function (orderData) {
self.orderData = orderData;
logger.log('orderData='+orderData);
logger.log('orderData name='+orderData.name);
})
.catch(function (err) {
logger.error('status=' + err.status + ' error=' + err.error);
self.msgCtrlError.id = err.status;
self.msgCtrlError.txt = err.error;
});
};
});
})();
and the [common] is like that :
(function() {
'use strict';
angular.module('common', [
'common.drivers-service',
'common.ads-auth-service',
'common.liferay-service',
'common.locale-service',
'common.logging-service'
]);
})();
and I tried to test it like that:
'use strict';
describe('orderModule', function () {
// Set up the module
beforeEach(module('common'));
beforeEach(module('order'));
var scope;
//test controller order
describe('OrderVehiculesController', function () {
var controller;
beforeEach(inject(function ($controller, $rootScope,common) {
scope = $rootScope.$new();
//TODO: how to call common mudule???
//instantiation of controller with its modules
controller = $controller('OrderVehiculesController', {
$scope: scope,
});
}));
it('should be defined', function() {
expect(OrderVehiculesController).toBeDefined();
});
});
});
but finaly, i've this error and i didn't understand it, i need some help please.
thank you.
ERROR is:
> WARN [watcher]: Pattern "C:\Users\src\**\*.mock.js" does not match any file.
> INFO [PhantomJS 1.9.8 (Windows 7)]: Connected on socket 4vwNDK9jjnvHoFW7eeL- with id 39484477
PhantomJS 1.9.8 (Windows 7) orderModule OrderVehiculesController should be defined FAILED
Error: [$injector:unpr] Unknown provider: commonProvider <- common
http://errors.angularjs.org/1.3.15/$injector/unpr?
and my karma config is the default karma.confg.js :
'use strict';
module.exports = function(config) {
var configuration = {
autoWatch : false,
frameworks: ['jasmine'],
ngHtml2JsPreprocessor: {
stripPrefix: 'src/',
moduleName: 'gulpAngular'
},
browsers : ['PhantomJS'],
plugins : [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor'
],
preprocessors: {
'src/**/*.html': ['ng-html2js']
}
};
// This block is needed to execute Chrome on Travis
// If you ever plan to use Chrome and Travis, you can keep it
// If not, you can safely remove it
// https://github.com/karma-runner/karma/issues/1144#issuecomment-53633076
if(configuration.browsers[0] === 'Chrome' && process.env.TRAVIS) {
configuration.customLaunchers = {
'chrome-travis-ci': {
base: 'Chrome',
flags: ['--no-sandbox']
}
};
configuration.browsers = ['chrome-travis-ci'];
}
config.set(configuration);
};

Mock not being used in Unit Test

I am stumped. I have written modal tests a few times now but in the controller I am currently testing I keep getting a TypeError: 'undefined' is not a function (evaluating 'pressReleaseCampaignService.deleteCampaign(global.activeOrganizationId, accountId, campaign.entityId) error. I want the test to use my mock however and Im not sure why it keep referencing the original controller. Does anyone see my mistake?
Controller:
angular.module('pb.campaigns.controllers')
.controller('ConfirmDeleteModalController', ['$scope', '$stateParams', '$state', '$modal', '$modalInstance', 'global', 'pbRoles', 'campaign', 'accountId', 'pressReleaseCampaignService',
function ($scope, $stateParams, $state, $modal, $modalInstance, global, pbRoles, pressReleaseCampaignService, campaign, accountId) {
$scope.campaign = campaign;
$scope.currentAccountId = accountId;
$scope.delete = function (accountId, campaign) {
global.setFormSubmitInProgress(true);
pressReleaseCampaignService.deleteCampaign(global.activeOrganizationId, accountId, campaign.entityId).then(function () {
global.setFormSubmitInProgress(false);
$modalInstance.close();
},
function (errorData) {
global.setFormSubmitInProgress(false);
});
};
$scope.cancel = function () {
global.setFormSubmitInProgress(false);
$modalInstance.dismiss('cancel');
};
}]);
Test:
describe('ConfirmDeleteModalController', function () {
beforeEach(module('pb.roles'));
beforeEach(module('pb.campaigns.controllers'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
var mockModalInstance = {};
var mockcampaignBuyRequestService = {};
var mockGlobal = {};
var mockStateParams = {};
var mockState = {};
var mockPbRoles = {};
beforeEach(inject(function ($q) {
mockGlobal = {
setFormSubmitInProgress: function (boolean) {
this.formProgress = boolean;
},
formProgress: false,
activeOrganizationId: 0
};
mockStateParams = {
orgId: 1,
accountId: 3,
entityId: 94,
campaignId: 45,
page: 3,
length: 12
};
mockModalInstance = {
close: jasmine.createSpy('mockModalInstance.close'),
dismiss: jasmine.createSpy('mockModalInstance.dismiss'),
result: {
then: jasmine.createSpy('mockModalInstance.result.then')
}
};
mockPressReleaseCampaignService = {
campaign: { entityId: 2, page: 19, length: 200 },
deleteCampaign: function (activeOrganizationId, entityId) {
var defer = $q.defer();
defer.resolve();
return defer.promise;
}
};
}));
beforeEach(inject(function ($rootScope, _$controller_) {
scope = $rootScope.$new();
$controller = _$controller_;
controller = $controller('ConfirmDeleteModalController', {
$modalInstance: mockModalInstance,
$scope: scope,
$stateParams: mockStateParams,
$state: mockState,
global: mockGlobal,
pbRoles: mockPbRoles,
pressReleaseCampaignService: mockPressReleaseCampaignService,
campaign: function () {
return mockPressReleaseCampaignService.campaign
},
accountId: function () {
return mockPressReleaseCampaignService.accountId
}
});
}));
describe("delete() function", function () {
it("calls deleteCampaign with proper params", function () {
spyOn(mockPressReleaseCampaignService, "deleteCampaign").and.callThrough();
scope.delete(mockStateParams.accountId, mockPressReleaseCampaignService.campaign);
expect(mockPressReleaseCampaignService.deleteCampaign).toHaveBeenCalledWith(mockGlobal.activeOrganizationId, mockStateParams.accountId, mockPressReleaseCampaignService.campaign.entityId);
});
it("calls close and toggles setFormSubmitionInProgress status", function () {
scope.delete(mockStateParams.accountId, mockPressReleaseCampaignService.campaign);
expect(mockGlobal.formProgress).toEqual(true);
scope.$digest();
expect(mockModalInstance.close).toHaveBeenCalled();
expect(mockGlobal.formProgress).toEqual(false);
});
});
describe("cancel() function", function () {
it("changes formProgress from true to false", function () {
mockGlobal.setFormSubmitInProgress.formProgress = true;
scope.cancel();
expect(mockModalInstance.dismiss).toHaveBeenCalled();
expect(mockGlobal.formProgress).toEqual(false);
});
});
});
The order of the service names is not the same as the order of the variables:
'campaign', 'accountId', 'pressReleaseCampaignService'
vs.
pressReleaseCampaignService, campaign, accountId
So, when your code calls a method on pressReleaseCampaignService, it actually calls a method on the campaign service.

Jasmine Test- Need to manually set values to be expected

For testing with Angular.js, Mocha, and Jasmine I have this test for DeviceVal value file:
describe("load balancer device: value", function() {
var DeviceVal;
DeviceVal = null;
beforeEach(function() {
return module("main.loadbalancer");
});
beforeEach(inject(function(_DeviceVal_) {
return DeviceVal = _DeviceVal_;
}));
return it("should default the id to 'device not loaded'", function() {
return expect(DeviceVal).toEqual({
readonly: false,
lb: "device not loaded"
});
});
});
For one of my other tests, I have this which uses the DeviceVal value file:
describe("load balancer controller: readonly", function() {
$scope = DeviceVal = LoadBalancerSvc = SearchSvc = $state = $sce = null;
beforeEach(function() {
module('main');
});
beforeEach(inject(function($controller, $rootScope, _$state_, _LoadBalancerSvc_, _DeviceVal_) {
$scope = $rootScope.$new();
$state = _$state_;
LoadBalancerSvc = _LoadBalancerSvc_;
DeviceVal = _DeviceVal_;
$controller('HeaderCtrl', {$scope: $scope});
//to resolve all the promises we have on the mocked service
$scope.$digest();
lb = { ha_status: "secondary", id: "34584"};
this.lb = lb;
spyOn(LoadBalancerSvc, "searchDevice").and.returnValue(
{get: function() {
return { then: function(fn) { fn(lb)} }}});
spyOn($state, "go");
}));
it('scope data memembers to have their stuff', function() {
$scope.searchButton.submit();
expect(lb).toEqual(this.lb);
expect(lb['ha_status']).toEqual("secondary");
expect(DeviceVal.readonly).toBe(true);
expect($state.go).toHaveBeenCalledWith("main.loadbalancer.vips", {id: this.lb.id});
});
});
The issue I am having is I want to manually set the values in the second test of DeviceVal to custom values. But instead, the test expects the values to be the values in the first DeviceVal test file. It complains of:
Expected { readonly : true, lb : { ha_status : 'secondary', id : '34584' } } to equal { readonly : false, lb : 'device not loaded' }.
How can I make the second test where I can manually set the values DeviceVal.lb = { ha_status: "secondary", id: "34584"}; and have expect(lb['ha_status']).toEqual("secondary"); and expect(DeviceVal.readonly).toBe(true);?
UPDATE:
Here it is with mock DeviceVal, but I still get Error: Expected { readonly : true, lb : { ha_status : 'secondary', id : '34584' } } to equal { readonly : fals
e, lb : 'device not loaded' }.:
describe("load balancer controller: readonly", function() {
$scope = DeviceVal = LoadBalancerSvc = SearchSvc = $state = $sce = null;
beforeEach(function() {
module('main');
});
beforeEach(inject(function($controller, $rootScope, _$state_, _LoadBalancerSvc_, _DeviceVal_) {
$scope = $rootScope.$new();
$state = _$state_;
LoadBalancerSvc = _LoadBalancerSvc_;
DeviceVal = _DeviceVal_;
$controller('HeaderCtrl', {$scope: $scope});
//to resolve all the promises we have on the mocked service
$scope.$digest();
//MY ATTEMPT AT MOCKING THIS DATA
DeviceVal.lb = { ha_status: "secondary", id: "34584"};
DeviceVal.readonly = true;
spyOn(LoadBalancerSvc, "searchDevice").and.returnValue(
{get: function() {
return { then: function(fn) { fn(DeviceVal.lb)} }}});
spyOn($state, "go");
}));
it('scope data memembers to have their stuff', function() {
$scope.searchButton.submit();
expect(DeviceVal.lb).toEqual({ha_status: "secondary", id: "34584"});
expect(DeviceVal.lb['ha_status']).toEqual("secondary");
expect(DeviceVal.readonly).toBe(true);
expect($state.go).toHaveBeenCalledWith("main.loadbalancer.vips", {id: DeviceVal.lb.id});
});
});
Fixed it. From http://angular-tips.com/blog/2014/06/introduction-to-unit-test-controllers/, I created the mock data like this:
describe("load balancer controller: readonly", function() {
$scope = DeviceVal = LoadBalancerSvc = SearchSvc = $state = $sce = null;
beforeEach(function() {
eviceVal = {}
module('main', function($provide) {
$provide.value('DeviceVal', eviceVal);
});
inject(function() {
eviceVal.lb = { ha_status: "secondary", id: "34584"};
eviceVal.readonly = true;
});
});

Resources