mardi 3 mai 2016

How to mock PushNotification and ionic.Platform.isAndroid() in Ionic

We develop an app with Cordova and Ionic framework and use phonegap-plugin-push. Things are working quite fine, but I'd like to write some unit tests for our Push functionality with Karma and Jasmine.

We have a factory PushNotificationService with a function register() , which is called when the user enables PushNotifications in the app settings. For now, I just want to unit test that PushNotification.init(...) is called when register() has been called.

However, this does not work as expected for two reasons:

  1. PhantomJS (which we use for the karma tests) is no mobile device, so ionic.Platform.isAndroid() and ionic.Platform.isIOS() return false and PushNotification.init(...) is never called. The test fails with Expected spy init to have been called.
  2. If I simply remove the if-statement checking for the platform, the error ReferenceError: Can't find variable: PushNotification is thrown.

While I was looking for a solution, I wondered where the ionic.Platform object and the PushNotification object are defined. Both are defined in the root scope (on the same level as angular and window).

Does anybody know a possibility to spy and mock function in global (root scope) variables? Or do you know another solution for my test case?

PushNotificationService

angular.module('myApp')
  .factory('PushNotificationService', function () {

function register() {
  if (ionic.Platform.isIPad() || ionic.Platform.isIOS() || ionic.Platform.isAndroid()) {
    var push = PushNotification.init({
      android: {
        senderID: "***********",
        icon: "icon",
        forceShow: true
      },
      ios: {
        alert: "true",
        badge: "true",
        sound: "true"
      },
      windows: {}
    });

    push.on('registration', onRegistration);
    push.on('notification', onNotification);
    push.on('error', onError);
  }
}

Test

describe('PushNotificationService', function () {

  beforeEach(module('myApp', function ($provide) {
    $provide.value('PushNotification', {
      init: jasmine.createSpy('init')
    });

    // try to mock ionic.Platform.isAndroid(), as PhantomJS is neither Android nor iOS
    $provide.value('ionic', {
      Platform: {
        isAndroid: function () {
          return true;
        }
      }
    })
  }));

  var PushNotificationService;
  var PushNotification;

  beforeEach(inject(function (_PushNotificationService_, _PushNotification_) {
    PushNotificationService = _PushNotificationService_;
    PushNotification = _PushNotification_;
  }));

  it('should call PushNotification.init()', function () {
    PushNotificationService.register();
    expect(PushNotification.init).toHaveBeenCalled();
  });
});

Aucun commentaire:

Enregistrer un commentaire