user3775998
user3775998

Reputation: 1543

unit test for service with a promise

I have a service that i wrote for a project i am currently working on and i am trying to write a unit test for it. Below is the code for the service

angular.module('services').factory('Authorization', ['$q', 'Refs', function($q, Refs) {

  function isAuthorized() {
    var deferred = $q.defer();

    var authData = Refs.rootRef.getAuth();
    var adminRef;

    if(authData.google) {
      adminRef = Refs.rootRef.child('admins').child(authData.uid);
    } else {
      adminRef = Refs.rootRef.child('admins').child(authData.auth.uid);
    }

    adminRef.on('value', function(adminSnap) {
      deferred.resolve(adminSnap.val());
    });
    return deferred.promise;
  }

  return {
    isAuthorized: isAuthorized
  };
}]);

I have written a unit test for it but anytime i run the test i get this error message ' Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'

Below is the code for the unit test i wrote for the service:

'use strict';

describe('Authorization Service', function() {

  var Refs, $q, Authorization, authData, scope, deferred;

  beforeEach(angular.mock.module('Sidetime'));

  beforeEach(inject(function(_Refs_, $rootScope, _$q_, _Authorization_) {
    Refs = _Refs_;
    $q = _$q_;
    Authorization = _Authorization_;
  }));

  iit('return admin object', function(done) {
    var result;

    Authorization.isAuthorized = function() {
      deferred = $q.defer();
      authData = {google: 'uid:112222'};

      if(authData.google) {
        deferred.resolve(authData);
      }

      return deferred.promise;
    };

    Authorization.isAuthorized().then(function(result) { 
      console.log('result', result);
      expect(result).toEqual(authData);
      //done();
    });
  });
});

I am not sure I am writing the unit test properly. I will appreciate if someone could show be a better way of writing the unit test for this service. Thanks for your anticipated assistance.

Upvotes: 1

Views: 1679

Answers (2)

mengstrom
mengstrom

Reputation: 233

Take a look over at spies in jasmine to get a deeper introduction

I've taken Cognitroics plunkr and modified it in the way I usually write my test. Take a look at it here http://plnkr.co/edit/W5pP82CKj7tc6IO3Wj9S?p=preview

But basically what you should do is utilizing the awesomeness of spies in jasmine.

Here's how it looks like.

describe('My aweomse test suite', function(){
    beforeEach(function(){
        module('Awesome');
        inject(function($injector){
           this.MyService = $injector.get('MyService');
           this.$q = $injector.get('$q');
           this.$scope = $injector.get('$rootScope').$new();

           spyOn(this.MyService, 'someMethod').andCallFake(function(){
              var defer = this.$q.defer();
              defer.resolve();
              return defer.promise;
           });
        });

        it('should do seomthing', function(){
            // given
            var result;

            // when
            this.MyServcie.someMethod().then(function(){
                result = 'as promised';
            });

            this.$scope.$digest();

            // then
            expect(result).toEqual('as promised');
        });
    });
});

Upvotes: 0

Cognitronic
Cognitronic

Reputation: 1436

Here is a working plunkr, with slight modifications as I don't have the code to all of your dependencies:

 angular.module('services', []).factory('Authorization', ['$q', function($q) {

  function isAuthorized() {
    var deferred = $q.defer();

    deferred.resolve({authData: {google: 'uid: 1122222'}});
    return deferred.promise;
  }

  return {
    isAuthorized: isAuthorized
  };
}]);


describe('Authorization Service', function() {

  var  $q, Authorization, scope, deferred;

  beforeEach(angular.mock.module('services'));

  beforeEach(inject(function($rootScope, _$q_, _Authorization_) {
    $q = _$q_;
    scope = $rootScope.$new();
    Authorization = _Authorization_;

    Authorization.isAuthorized = function() {
      deferred = $q.defer();
      authData = {google: 'uid:112222'};

      if(authData.google) {
        deferred.resolve(authData);
      }

      return deferred.promise;
    };
  }));

  it('return admin object', function(done) {
    var result;

    var promise = Authorization.isAuthorized();

    promise.then(function(result) {
      expect(result).toEqual(authData);
      expect(result.google).toEqual('uid:112222e');
    });

    deferred.resolve(result);
    scope.$digest();


  });
});



(function() {
  var jasmineEnv = jasmine.getEnv();
  jasmineEnv.updateInterval = 250;

  /**
   Create the `HTMLReporter`, which Jasmine calls to provide results of each spec and each suite. The Reporter is responsible for presenting results to the user.
   */
  var htmlReporter = new jasmine.HtmlReporter();
  jasmineEnv.addReporter(htmlReporter);

  /**
   Delegate filtering of specs to the reporter. Allows for clicking on single suites or specs in the results to only run a subset of the suite.
   */
  jasmineEnv.specFilter = function(spec) {
    return htmlReporter.specFilter(spec);
  };

  /**
   Run all of the tests when the page finishes loading - and make sure to run any previous `onload` handler

   ### Test Results

   Scroll down to see the results of all of these specs.
   */
  var currentWindowOnload = window.onload;
  window.onload = function() {
    if (currentWindowOnload) {
      currentWindowOnload();
    }

    //document.querySelector('.version').innerHTML = jasmineEnv.versionString();
    execJasmine();
  };

  function execJasmine() {
    jasmineEnv.execute();
  }
})();

http://plnkr.co/edit/DCrr6pVzF9D4OuayCZU7?p=preview

Upvotes: 1

Related Questions