Colin
Colin

Reputation: 168

Unit Testing a Confirmation Popup Ionic Framework Karma

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

Answers (1)

Phransys
Phransys

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

Related Questions