$uibModal.open is not a function in karma (AngularJS Factory) - angularjs

I am trying to test a function that opens a $uibmodal. This is my factory function.
confirmationMessage: function (message) {
var modalInstance = $uibModal.open({
templateUrl: 'views/templates/utilsTemplates/confirmationMessage.html',
backdrop: 'static',
controller: function () {
var messageCtrlVM = this;
// message to show
messageCtrlVM.message = message;
// when yes_button is pressed
messageCtrlVM.yesPress = function () {
modalInstance.close(true);
};
// when no_button is pressed
messageCtrlVM.noPress = function () {
modalInstance.close();
};
},
controllerAs: "messageCtrlVM"
});
return modalInstance.result;
},
In its unit testing file, I am first adding provider for it like so.
beforeEach(angular.mock.module('ui.bootstrap'));
beforeEach(function () {
module(function ($provide) {
$provide.value('$uibModal', function (value) {
return value;
});
});
});
After that I am injecting open, dismiss and close functions with beforeEach like so.
beforeEach(inject(function (_utilsFactory_, _$httpBackend_, _$filter_) {
utilsService = _utilsFactory_;
$httpBackend = _$httpBackend_;
filter = _$filter_;
uibModal = {
open: function () {},
dismiss: function () {},
close: function () {}
};
}));
Finally I am trying to run my unit test by calling factory function.
it('should show a confirmation message', function () {
var spy = spyOn(uibModal, "open").and.callFake(function () {
return {
result: {
then: function () {}
}
};
});
utilsService.confirmationMessage("Are you Sure?");
expect(spy).toHaveBeenCalled();
});
It gives me error that $uibModal.open is not a function.

Your beforeEach should be like this:
beforeEach(module('myApp', function ($provide) {
mockModal = {
result: {
then: function(confirmCallback, cancelCallback) {
this.confirmCallback = confirmCallback;
this.cancelCallback = cancelCallback;
return this;
}
},
opened: {
then: function (confirmCallback, cancelCallback) {
this.confirmCallback = confirmCallback;
this.cancelCallback = cancelCallback;
return this;
}
},
close: function() {
this.opened.confirmCallback(); // covers opened.then success
this.result.confirmCallback(); // covers result.then success
this.result.cancelCallback(); // covers result.then error
},
open: function (object1) {
return this;
}
};
$provide.value('$uibModal', mockModal);
}));
Note that, here, the object which we are providing as $uibModal has the open function. Having this passed in $provide, you would need to callThrough (not callFake after spying)
Feel free to remove result / opened / close if you are not using them here. They are useful when you have corresponding code.

Related

How to Spy on a method of Service from controller?

I am writing the UT for controller and while trying to implement for commandRouter.execute method(please refer 2nd spec) , I am getting error message : can not read property 'execute' of undefined.
Can someone let me know what am i doing wrong here and whats the correct way to spy on a method from controller. ?
module.controller('DcsPlus.AP.OmsControl.omsMasterRecipeDialogPopUpController', omsMasterRecipeDialogPopUpController);
omsMasterRecipeDialogPopUpController.$inject = [
'DcsPlus.Frame.Logic.commandRouter'
];
function omsMasterRecipeDialogPopUpController(commandRouter) {
var vm = this;
vm.execute = function(command) {
commandRouter.execute(command);
};
}
controller.spec.js
describe('omsMasterRecipeDialogPopUpController', function () {
var omsMasterRecipeDialogPopUpControllerTest;
var commandRouterMock;
var $scope;
beforeEach(function () {
registerMockServices();
prepareCommandRouterMock();
});
describe('execute', function () {
it('1. Should check if execute method is defined', function() {
expect(omsMasterRecipeDialogPopUpControllerTest.execute).toBeDefined();
});
it('2. Should check if execute method of commandRouter is called', function() {
omsMasterRecipeDialogPopUpControllerTest.execute();
expect(commandRouterMock.execute).toHaveBeenCalled();
});
});
function prepareCommandRouterMock() {
commandRouterMock = {
execute: function() {
}
};
}
/*beforeEach(function () {
commandRouterMock = jasmine.createSpyObj('DcsPlus.Frame.Logic.commandRouter', ['execute']);
});*/
function registerMockServices() {
angular.mock.module('DcsPlus.AP.OmsControl', function ($provide) {
$provide.value('DcsPlus.Frame.Logic.commandRouter', commandRouterMock);
});
angular.mock.inject(['$controller', '$rootScope', 'dialogService',
function ($controller, $rootScope, dialogService) {
$scope = $rootScope.$new();
spyOn(commandRouterMock, 'execute').and.callThrough();
// Init the controller, passing our spy service instance
omsMasterRecipeDialogPopUpControllerTest = $controller('DcsPlus.AP.OmsControl.omsMasterRecipeDialogPopUpController', {
$scope: $scope
});
}]);
}
});
In the beginning you create commandRouterMock but never assign it to anything.
Try this:
beforeEach(function () {
registerMockServices();
commandRouterMock = prepareCommandRouterMock();
});
function prepareCommandRouterMock() {
return {
execute: function() {
}
};
}

How to write angularjs unit test for interval which is in a run block

I am writing unit test for $interval. The code is like this:
angular.module('serviceInvoker', []).
run(function($rootScope, $http, $interval, DateTimeFormatter) {
$rootScope.loadData = function(serviceName, dataName) {
$http.get(serviceName)
.then(function(result) {
serviceSuccessFunc(result, dataName)
})
.catch(function(error) {
serviceErrorFunc(error, dataName)
});
$rootScope.current = moment().toISOString();
$rootScope.now = moment($rootScope.current).format(DateTimeFormatter.DayHoursFormat);
};
$rootScope.autoRefresh = function(serviceName, dataName, interval) {
$interval(function() {
$rootScope.loadData(serviceName, dataName)
}, interval);
};
var serviceSuccessFunc = function(result, dataName) {
$rootScope[dataName] = result.data;
};
var serviceErrorFunc = function(error, dataName) {
$rootScope[dataName] = error;
};
});
The test code is like this:
describe('serviceInvoker', function() {
beforeEach(module('serviceInvoker'));
beforeEach(module(function($provide) {
$provide.value('DateTimeFormatter', {
DayHoursFormat: 'HH:mm'
});
$provide.value('serviceSuccessFunc', jasmine.createSpy());
$provide.value('serviceErrorFunc', jasmine.createSpy());
}));
var $interval;
beforeEach(inject(function (_$rootScope_, _$interval_, _serviceSuccessFunc_, _serviceErrorFunc_) {
$rootScope = _$rootScope_;
scope = $rootScope.$new();
$interval = _$interval_;
serviceSuccessFunc = _serviceSuccessFunc_;
serviceErrorFunc = _serviceErrorFunc_;
}));
describe("loadData function ", function () {
it("should expose loadData function to $rootScope", function () {
expect(angular.isFunction($rootScope.loadData)).toBe(true);
});
it("should be called", inject(function($http) {
spyOn($rootScope, 'loadData');
$rootScope.loadData('service', 'data');
expect($rootScope.loadData).toHaveBeenCalledWith('service', 'data');
}));
});
describe("autoRefresh function ", function () {
it("should expose autoRefresh function to $rootScope", function () {
expect(angular.isFunction($rootScope.autoRefresh)).toBe(true);
});
it("should be called", function() {
var $intervalspy = jasmine.createSpy('$interval', $interval);
spyOn($rootScope, 'autoRefresh').and.callThrough();
$rootScope.autoRefresh('service', 'data','interval');
expect($rootScope.autoRefresh).toHaveBeenCalledWith('service', 'data', 'interval');
expect($intervalspy).toHaveBeenCalled();
// expect($intervalspy).toHaveBeenCalledWith(jasmine.any(Function), 1000);
});
});
});
But there is an error for interval: Error: Expected spy $interval to have been called.
I don't know how to write unit test for interval which is inside a function(in a run block), can anyone give me some help?
$intervalspy isn't used anywhere but the test itself. It isn't called.
As any other tested service, $interval should be spied, mocked or stubbed. It can be spied with a decorator like that, and stubbing is even simpler:
beforeEach(() => {
module({ $interval: jasmine.createSpy() })
});
...
$rootScope.autoRefresh('service', 'data', 'interval');
expect($interval).toHaveBeenCalledWith(jasmine.any(Function), 'interval');
expect($rootScope.loadData).not.toHaveBeenCalled(),
var intervalCallback = $interval.calls.first().args[0];
intervalCallback();
expect($rootScope.loadData).toHaveBeenCalledWith(...),

Unit testing- $state.includes error is blocking other tests /how to mock state

I am trying to unit test the init function of this controller.I cannot find a way of doing this and keep getting the error
TypeError: 'undefined' is not a function (evaluating '$state.includes('profile.details')')
My main concern is to mock the state so that this error goes away and my other tests can pass and then I will focus on writing the test for the init statement. I have tried mocking the state as a string and using transitionTo, has anyone else found a way of testing includes for states?
var init = function () {
$scope.global = global;
$scope.partialViews = {
personForm: "/app/users/views/details/_personForm.html",
passwordForm: "/app/users/views/details/_passwordForm.html"
};
if (!$state.includes('profile.details') && !$state.includes('profile.organizations')) {
if (global.activeProfile.defaultOrganizationId) {
$state.go("dashboard.notifications", { orgId: global.activeProfile.defaultOrganizationId });
} else {
$state.go("profile.organizations");
}
}
};
As an aside I went back to reading the docs to see how the .includes method works in hopes that it would help me figure out what I am doing wrong in my unit tests. in the MDN docs the .includes example is [1, 2, 3].includes(2); but typing this into the console responded with a
Uncaught TypeError: undefined is not a function
why is that?
my tests:
beforeEach(module('pb.users.controllers'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
var mockUserService = {};
var mockOrganizationService = {};
var mockPersonInvitationService = {};
var mockStateParams = {};
var mockState = "profile.details";
var mockGlobal = {};
var mockForm = {};
var mockModal = {};
var invitation = {};
beforeEach(inject(function ($q) {
invitation = {
organizationId: 6542643
};
mockForm = {
submitIfValid: function (promiseHandler) {
return promiseHandler();
}
};
mockStateParams = {
accountId: 7672891,
entityId: 532,
orgId: 67,
page: 43,
length: 12
};
mockGlobal = {
setFormSubmitInProgress: function (boolean) {
this.formProgress = boolean;
},
formProgress: false,
activeOrganizationId: 432,
organizationsUpdated: function () {
return "updated!"
}
};
mockUserService = {
user: {
person: {
name: 'Regan Perkins'
}
},
getUser: function () {
var defer = $q.defer();
defer.resolve(this.user);
return defer.promise;
},
updateExtendedInfo: function (person) {
var defer = $q.defer();
defer.resolve(this.user);
return defer.promise;
}
};
mockOrganizationService = {
organizations: {
groups: ["PressBoard", "MySite"]
},
getOrganizations: function () {
var defer = $q.defer();
defer.resolve(this.organizations);
return defer.promise;
}
};
mockPersonInvitationService = {
invitations: ["invite one", "invite two"],
getInvitations: function () {
var defer = $q.defer();
defer.resolve(this.invitations);
return defer.promise;
},
acceptInvitation: function (organizationId) {
var defer = $q.defer();
defer.resolve(invitation);
return defer.promise;
}
};
}));
beforeEach(inject(function ($rootScope, _$controller_) {
scope = $rootScope.$new();
$controller = _$controller_;
controller = $controller('ProfilesController', {
$scope: scope,
$stateParams: mockStateParams,
$state: mockState,
$modal: mockModal,
global: mockGlobal,
userService: mockUserService,
organizationService: mockOrganizationService,
personInvitationService: mockPersonInvitationService
});
}));
describe('init() function', function () {
it('should set activeOrganizationId', function () {
expect(scope.global.activeOrganizationId).toEqual(mockGlobal.activeOrganizationId);
});
it('should set global', function () {
expect(scope.global).toEqual(mockGlobal);
});
});
describe('get() function', function () {
it('should resolve a promise', function () {
scope.get();
scope.$digest();
expect(scope.person).toEqual(mockUserService.user.person);
});
});
describe("edit() function", function () {
it("should toggle personFormSuccess", function () {
spyOn(mockUserService, "updateExtendedInfo").and.callThrough();
scope.edit(mockForm, mockUserService.user);
expect(mockUserService.updateExtendedInfo).toHaveBeenCalledWith(mockUserService.user);
});
it("should call updateExtendedInfo()", function () {
spyOn(mockUserService, "updateExtendedInfo").and.callThrough();
scope.edit(mockForm, mockUserService.user);
expect(scope.personFormSuccess).toBe(false);
scope.$digest();
expect(scope.personFormSuccess).toBe(true);
});
});
describe('getOrganizations() function', function () {
it('should resolve a promise', function () {
scope.getOrganizations();
scope.$digest();
expect(scope.organizations).toEqual(mockOrganizationService.organizations);
});
});
describe('getInvitations() function', function () {
it('should resolve a promise', function () {
scope.getInvitations();
scope.$digest();
expect(scope.invitations).toEqual(mockPersonInvitationService.invitations);
});
});
describe('acceptInvitation() function', function () {
it('should toggle form progress', function () {
scope.invitations = mockPersonInvitationService.invitations;
scope.acceptInvitation(invitation, 1);
scope.$digest();
expect(scope.invitations).toEqual(mockPersonInvitationService.invitations);
});
it('should resolve a promise', function () {
scope.invitations = mockPersonInvitationService.invitations;
scope.acceptInvitation(invitation, 1);
scope.$digest();
expect(scope.invitations).toEqual(mockPersonInvitationService.invitations);
});
it('should resolve a promise', function () {
scope.invitations = mockPersonInvitationService.invitations;
scope.acceptInvitation(invitation, 1);
scope.$digest();
expect(scope.invitations).toEqual(['invite one']);
});
});
describe("openRejectInvitation() function", function () {
var actualOptions;
var modalOptions = {
templateUrl: '/app/users/views/organizations/_removeInvite.html',
controller: 'RejectInvitationModalController',
resolve: {
invitation: function () {
return invitation;
}
}
};
beforeEach(inject(function ($injector, $q) {
mockModal.open = function (options) {
actualOptions = options;
var defer = $q.defer();
defer.resolve();
return { result: defer.promise };
}
}));
it("make sure modalInstance.result.then is executed", function () {
scope.invitations = mockPersonInvitationService.invitations;
scope.openRejectInvitation(invitation, 1);
expect(scope.invitations).toEqual(['invite one', 'invite two']);
scope.$digest();
expect(scope.invitations).toEqual(['invite one']);
});
it("make sure modal.open is called", function () {
spyOn(mockModal, 'open').and.callThrough();
scope.openRejectInvitation(invitation, 1);
expect(mockModal.open).toHaveBeenCalledWith(actualOptions);
});
it("make sure 'webSite' is passed by modalInstance.resolve", function () {
scope.openRejectInvitation(invitation, 1);
expect(actualOptions.resolve.invitation()).toEqual(invitation);
});
});
});
Incase this helps anyone else with this problem the way I was able to bypass this error was to mock the includes method on my mockState.
var mockState = {
includes: function (string) {
return false
}
};

Unknown Provider when unit testing filter

I am unit testing my first filter, which seems easy enough but I keep getting
Unknown provider: activeProfileProvider <- activeProfile <- pbRoles <- rolesFilter
The activeProfile is a consent that is a dependency of pbRoles. My understanding of constants is limited and I cant seem to find a way to include it. I have tried adding the config file where the constants are declared as well as mocking the constant in the test to no avail.
does anyone know if there is a specific way to do this? or does my problem lay else where?
My filter:
angular.module('pb.roles.filters')
.filter('roles', ['pbRoles', function (pbRoles) {
return function (input) {
if (!input) {
return "None";
} else {
return pbRoles.roleDisplayName(input);
}
};
}]);
My test:
describe('RolesController', function () {
beforeEach(module('pb.roles'));
beforeEach(module('pb.roles.filters'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
var rolesFilter;
var mockActiveProfile = {};
beforeEach(inject(function (_rolesFilter_) {
activeProfile = mockActiveProfile;
rolesFilter = _rolesFilter_;
}));
var pbRoles = {
roleDisplayName: function (input) {
return input
}
};
describe('role: filter', function () {
it('should return None if called with no input', function () {
expect(rolesFilter()).toBe('None');
});
it('should call roleDisplayName with input', function () {
expect(roles('Hello')).toBe('Hello');
});
});
});
have also tried mocking the constent like so:
module(function ($provide) {
$provide.constant('activeProfile', function () {
pbGlobal.activeProfile = {
profile: ""
}
});
});
mocking the providers at the top of the page like so worked:
beforeEach(module(function ($provide) {
$provide.constant('organizationService', function () {
});
$provide.service('activeProfile', function () {
activeProfile = {
profile: ""
}
});
}));
http://www.sitepoint.com/mocking-dependencies-angularjs-tests/ was a huge help.
My full working test if anyone is curious:
describe('RolesController', function () {
var mockPbRoles = {
roleDisplayName: function (input) {
return "it worked!"
}
};
beforeEach(module(function ($provide) {
$provide.value('pbRoles', mockPbRoles);
$provide.constant('organizationService', function () {});
$provide.service('activeProfile', function () { });
}));
beforeEach(module('pb.roles'));
beforeEach(module('pb.roles.filters'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
var rolesFilter;
beforeEach(inject(function (_rolesFilter_) {
rolesFilter = _rolesFilter_;
}));
describe('role: filter', function () {
it('should return None if called with no input', function () {
expect(rolesFilter(false)).toBe('None');
});
it('should call roleDisplayName with input', function () {
result = rolesFilter(true);
expect(result).toEqual("it worked!");
});
});
});

Need help completing unit test for angular $modal

I am trying to get the "make sure modalInstance.result.then is executed" test in my code to pass. Right now it says Expected [ undefined, 'http://www.link1.com', 'http://www.link2.com', 'http://www.link3.com' ] to contain 'http://www.pressboardmedia.com' I believe this has something to do with the promise needing to be mocked so it passes along the campaignLink but I am unsure if this is the problem and cannot seem to get it to work regardless. please let know if you have any ideas.
Thanks!
Controller File
angular.module('pb.campaignLinks.controllers')
.controller('CampaignLinksController', ['$scope', '$timeout', '$modal', '$stateParams', 'global', 'campaignLinkService', function ($scope, $timeout, $modal, $stateParams, global, campaignLinkService) {
$scope.init = function (currentView) {
$scope.partialViews = {
campaignLinkList: "/app/campaignLinks/views/_list.html",
};
$scope.currentView = currentView;
$scope.getCampaignLinks(currentView, 10);
};
$scope.getCampaignLinks = function (currentView, length, continuationToken) {
// When loading list items, display loading image
if ($scope.campaignLinks) $scope.campaignLinks.loading = true;
var promiseObj = null;
if (currentView.campaignId && currentView.campaignId !== 0 && !currentView.buyRequestId) {
promiseObj = campaignLinkService.getCampaignLinks(global.activeOrganizationId, currentView.campaignId, length, continuationToken)
} else if (currentView.campaignId && currentView.buyRequestId && currentView.campaignId !== 0 && currentView.buyRequestId !== '') {
promiseObj = campaignLinkService.getCampaignBuyRequestLinks(global.activeOrganizationId, currentView.campaignId, currentView.buyRequestId, length, continuationToken);
} else if (currentView.webSiteId && currentView.buyRequestId && currentView.webSiteId !== 0 && currentView.buyRequestId !== '') {
promiseObj = campaignLinkService.getWebSiteBuyRequestLinks(global.activeOrganizationId, currentView.webSiteId, currentView.buyRequestId, length, continuationToken);
}
if (promiseObj) {
promiseObj.then(function (data) {
// If there are already some campaign links being displayed, add newly loaded list to the end
if ($scope.campaignLinks) {
$scope.campaignLinks.continuationToken = data.continuationToken;
$scope.campaignLinks.total += data.total;
$.each(data.items, function (index) {
$scope.campaignLinks.items.push(data.items[index]);
});
} else {
// Otherwise add loaded list to scope
$scope.campaignLinks = data;
}
// When done loading, hide loading image
$scope.campaignLinks.loading = false;
});
}
};
$scope.openAddCampaignLink = function (campaignId) {
var modalOptions = {
templateUrl: '/app/campaignLinks/views/_add.html',
controller: 'AddCampaignLinksModalController',
resolve: {
campaignId: function () {
return campaignId;
}
}
};
var modalInstance = $modal.open(modalOptions);
modalInstance.result.then(function (campaignLink) {
// Add new item to list, otherwise wait for it to be loaded manually.
$scope.campaignLinks.items.unshift(campaignLink);
$scope.campaignLinks.total += 1;
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
};
$scope.openRemoveCampaignLink = function (campaignId, campaignLink, index) {
var modalOptions = {
templateUrl: '/app/campaignLinks/views/_delete.html',
controller: 'RemoveCampaignLinksModalController',
resolve: {
campaignId: function () {
return campaignId;
},
campaignLink: function () {
return campaignLink;
}
}
};
var modalInstance = $modal.open(modalOptions);
modalInstance.result.then(function () {
// Splice the deleted item from the list without reloading all
$scope.campaignLinks.items.splice(index, 1);
$scope.campaignLinks.total -= 1;
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
};
// Once everything is loaded, initialize controller
// init();
}]);
Test file:
describe('CampaignLinksController', function () {
//make module avalible to tests
beforeEach(module('pb.campaignLinks.controllers'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
var $controller;
var mockPromiseObj;
var length = 200;
var mockModal = {};
var mockCampaignLinks = {
total: 3,
items: ['http://www.link1.com', 'http://www.link2.com', 'http://www.link3.com']
};
var mockCurrentView = {};
var mockGlobal = { activeOrganizationId: 54 };
var continuationToken = {
nextRowKey: 'fdsf2',
nextPartitionKey: '5432gee'
};
var campaignDetails = {
campaignId: 453,
campaignLink: 'http://www.pressboardmedia.com',
index: 1
};
var mockCampaignLinkService = {
//move campaignDetails here
campaignLinks: {
total: 3,
//length here
items: ['http://www.link1.com', 'http://www.link2.com', 'http://www.link3.com']
},
//all but delete must return a promiseObj
getCampaignLinks: jasmine.createSpy('mockCampaignLinkService.getCampaignLinks').and.returnValue(mockPromiseObj),
getCampaignBuyRequestLinks: jasmine.createSpy('mockCampaignLinkService.getCampaignBuyRequestLinks').and.returnValue(mockPromiseObj),
getWebSiteBuyRequestLinks: jasmine.createSpy('mockCampaignLinkService.getWebSiteBuyRequestLinks').and.returnValue(mockPromiseObj),
deleteCampaignLink: jasmine.createSpy('mockCampaignLinkService.deleteCampaignLinks')
};
beforeEach(inject(function (_$controller_) {
$controller = _$controller_;
}));
beforeEach(inject(function ($rootScope) {
controller = $controller('CampaignLinksController',
{
$scope: scope,
$modal: mockModal,
//$stateParams: mockStateParams,
global: mockGlobal,
campaignLinks: mockCampaignLinks,
campaignLinkService: mockCampaignLinkService,
currentVeiw: mockCurrentView,
//promiseObj: mockPromiseObj
});
}));
describe('openAddCampaignLink()', function () {
var actualOptions;
var modalOptions = {
templateUrl: '/app/campaignLinks/views/_add.html',
controller: 'AddCampaignLinksModalController',
resolve: {
campaignId: jasmine.any(Function)
}
};
beforeEach(inject(function ($q) {
mockModal.open = function (options) {
actualOptions = options;
var defer = $q.defer();
defer.resolve();
return { result: defer.promise };
}
}));
it("make sure modalInstance.result.then is executed", function () {
scope.campaignLinks = mockCampaignLinkService.campaignLinks;
scope.openAddCampaignLink(campaignDetails.campaignId, campaignDetails.campaignLink, campaignDetails.index);
scope.$digest();
expect(scope.campaignLinks.total).toEqual(4);
expect(scope.campaignLinks.items).toContain(campaignDetails.campaignLink);
});
});
I think your problem is that the argument "campaignLink" that is supplied to your modalInstance.result.then function will always be undefined when you test this. The code that calls the modal close should be tested that it is supplying the campaignLink correctly. You only want to test that the proper code gets executed when the modal is closed. We do that by supplying a function that can be tested on it's own to the modalInstance.result.then call instead of doing an inline function so it can be tested easier.
Here's an example:
Here's the code that opens the modal:
$scope.editGradeClick = function () {
var modalInstance = $modal.open({
templateUrl: templateSrv.templateUrl('/Templates/App/Courses/CourseLessonGradeModal.html'),
controller: courseLessonGradeModalBootstrap,
backdrop: 'static',
keyboard: false,
resolve: {
data: $scope.editGradeModalResolve
}
});
modalInstance.result.then(
null,
$scope.editGradeModalDismissCallback
);
};
Notice how we supply a function $scope.editGradeModalDismissCallback instead of writting an inline function there for a modal dismiss. This allows us to test that logic in it's own test.
Now here is the test. We only care that the above function was called since we will be testing the specific function in it's own test. That happens at the last line in the test.
var $controllerConstructor, $scope, $q;
beforeEach(function () {
module('appModule');
inject(function ($controller, $rootScope, _$q_) {
$controllerConstructor = $controller;
$scope = $rootScope.$new();
$q = _$q_;
});
});
it('should execute $scope.editGradeModalDismissCallback when modal is dismissed', inject(function (templateSrv) {
var $modal = {};
$modal.open = function () {
var queryPromise = $q.defer();
queryPromise.reject();
return { result: queryPromise.promise };
};
$controllerConstructor('CourseLessonGradeListCtrl', { $scope: $scope, $modal: $modal, templateSrv: templateSrv});
spyOn($modal, "open").andCallThrough();
spyOn($scope, "editGradeModalDismissCallback");
$scope.editGradeClick();
$scope.$root.$digest();
expect($scope.editGradeModalDismissCallback).toHaveBeenCalled();
}));
I hope this helps you. In this example we are rejecting the promise because we are testing the modal dismiss not close, fyi...

Resources