Mock ionic.Platform methods


#1

Trying to write some tests for a controller that checks which platform we’re currently on. The issue I’m running into is, I’d like to be able to fake which type of device for various tests. So…I’m trying to mock ionic.Platform.whatever() so I can return a fake value and have my nested controller logic get fully tested.

I can’t seem to be able to inject my mocked ionic service into the controller though to mock different platform method calls. How can I do this?

controller.js

angular.module('app.controllers', [])
.controller('itemCtrl', function ($scope, resolvedItem) {

$scope.devicePlatform = ionic.Platform.platform(); //this is always my local computer platform

$scope.item = resolvedItem;

$scope.dialNumber = function(phoneNumber){

    if(ionic.Platform.isIOS()){  //this spy never gets called
        window.location.href = 'tel:'+phoneNumber;
    }else{
        window.open('tel:' + phoneNumber, '_system');
    }

};


})

test.js

describe('itemController', function () {

var itemController, scope, ionic;

// Load the App Module
beforeEach(module('app'));

beforeEach(module(function ($provide) {

    $provide.service('ionic', function () {
        return {
            Platform:{
                isAndroid:function(){
                    return false;
                },
                isIOS:function(){
                    return false;
                },
                platform:function(){
                    return false;
                }
            }
        }
    });
}));

beforeEach(inject(function ($controller, _$rootScope_) {

    scope = _$rootScope_.$new();
    ionic  = _ionic_;

    itemController = $controller('itemCtrl', {
        $scope: scope,
    });

    spyOn(ionic.Platform, 'isIOS').and.returnValue(true);

}));


it("Should have a dialNumber method", function(){
    expect(scope.devicePlatform).toEqual('IOS') //this fails
    scope.dialNumber(5555555555);
    expect(ionic.Platform.isIOS).toHaveBeenCalled();

    });
});

#2

Kept chopping & figured it out. The documentation for testing in ionic lacking but seeing this example was helpful.

https://gist.github.com/DavidFrahm/0e0403d38c86da77e2d1

Turns out ionic is actually stored on the $window object.

beforeEach(inject(function ($controller, _$rootScope_, _$window_) {
        scope = _$rootScope_.$new();
        $window = _$window_;

        spyOn($window.ionic.Platform, 'platform').and.returnValue('rocketdog');

        placesController = $controller('itemCtrl', {
            $scope: scope,
            $window: window
        });
    }
))