Reputation: 168
How should I go about testing both results of a confirmation box using karma and jasmine? I have some basic tests running, thanks to a helpful individual on here, but I'm having a difficult time mocking the ionicPopup.
It would be ideal if I could test all the way from the ng-click that calls the box to all possible results.
View:
<button ng-click="openPopup()">Open Popup</button>
Controller:
angular.module('starter.thisController', [])
.controller('ThisCtrl', function($scope, $state, $timeout, $ionicPopup) {
$scope.openPopup = function() {
var openPopup = $ionicPopup.confirm({
title: 'Confirm',
template: 'Are you sure?'
});
openPopup.then(function(res) {
if(res) {
$scope.confirmClicked();
}
});
$timeout(function() {
openPopup.close();
}, 5000);
};
$scope.confirmClicked = function() {
alert("User Clicked Confirm!!!");
};
});
Current Tests:
describe('This Controller', function() {
var scope, state, timeout, ionicPopup;
ionicPopup = jasmine.createSpyObj('$ionicPopup spy', ['confirm']);
beforeEach(module('starter.thisController'));
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
$controller('ThisCtrl', {
'$scope': scope,
'$state': state,
'$timeout': timeout,
'$ionicPopup': ionicPopup
});
}));
describe('Popup', function() {
it('should be defined', function() {
expect(ionicPopup).toBeDefined();
});
});
});
Thank you for any help you can provide :D.
Upvotes: 2
Views: 1736
Reputation: 146
I had the same problem and I solved it by using spyOn. I'll try to cater it to your example.
describe('This Controller', function() {
var scope, state, timeout, $ionicPopup, $q
beforeEach(module('starter.thisController'));
beforeEach(inject(function($rootScope, $controller, _$ionicPopup_, _$q_) {
scope = $rootScope.$new();
$ionicPopup = _$ionicPopup_;
$q = _$q_;
$controller('ThisCtrl', {
'$scope': scope,
'$state': state,
'$timeout': timeout,
'$ionicPopup': $ionicPopup
});
}));
describe('$scope.openPopup', function() {
it('should call confirmClicked function if ok is clicked in the confirm popup', function() {
var deferred = $q.defer();
deferred.resolve(true); //ok is clicked
spyOn($ionicPopup, 'confirm').and.callFake(function(){return deferred.promise});
scope.openPopup();
scope.$digest();
expect(scope.confirmClicked).toHaveBeenCalled();
});
it('should not call confirmClicked if cancel is clicked in the confirm popup', function() {
var deferred = $q.defer();
deferred.resolve(false); //cancel is clicked
spyOn($ionicPopup, 'confirm').and.callFake(function(){return deferred.promise});
scope.openPopup();
scope.$digest();
expect(scope.confirmClicked).not.toHaveBeenCalled();
});
});
});
The main difference here is that we are injecting the real $ionicPopup and then overriding its behavior with spyOn.
Upvotes: 3