lundi 8 août 2016

Testing Angular Service in Karma: Same Test, Different Results

I'm trying to test an Angular service with Karma, and was getting some strange results, so just for kicks I made two tests that were identical to see if I would get the same results, but I didn't:

describe('Profile Data Service', function() {
  var LoginData, rootScope, $httpBackend;
  beforeEach(module('myApp'));

  describe('get profile data', function() {
    beforeEach(inject(function(_LoginData_, $rootScope, _$httpBackend_) {
      LoginData = _LoginData_;
      LoginData.username= "jsmith";
      LoginData.token = "token";

      rootScope = $rootScope;

      $httpBackend = _$httpBackend_;

    }));

    it('should get profile data on instantiation', inject(function(ProfileDataService) {
      $httpBackend.expect('POST', 'http://ift.tt/2aN1kDm', {
        params: [{
          username: "jsmith",
          token: "token",
          method: "getProfile"
        }]
      })
      .respond({
        result: {
          address: "111 Main St."
          city: "Los Angeles",
          state: "CA"
        }
      });
      $httpBackend.flush();
      expect(ProfileDataService.profileData.address).toMatch("111 Main St.");
    }));

    it('should get profile data on instantiation', inject(function(ProfileDataService) {
      $httpBackend.expect('POST', 'http://ift.tt/2aN1kDm', {
        params: [{
          username: "jsmith",
          token: "token",
          method: "getProfile"
        }]
      })
      .respond({
        result: {
          address: "111 Main St."
          city: "Los Angeles",
          state: "CA"
        }
      });
      $httpBackend.flush();
      expect(ProfileDataService.profileData.address).toMatch("111 Main St.");
    }));
  });
});

The first test passes, but the second test states that profileData is undefined. They are identical tests. I am assuming that for each it that the ProfileDataService is being re-initialized, but that may not be the case. If that's not true, how do I create separate tests so that my service is destroyed and re-initialized for each test case?

The logic for the service is fairly straightforward:

(function() {
  'use strict';
  angular.module('servicesModule')
  .service('ProfileDataService', ProfileDataService);

  ProfileDataService.$inject = ["$http", "$q", "LoginData"];

  function ProfileDataService($http, $q, LoginData) {
    var ProfileDataService = this;
    (function() {
      init();
    })();

    function init() {
      getProfile().then(function(profileData) {
        ProileDataService.profileData = profileData;
      });
    }

    function getProfile() {
      var deferred = $q.defer();
      $http.post('http://ift.tt/2aN1kDm', data)
      .success(function(data) {
         deferred.resolve(data.result);
       });
      return deferred.promise;
    }
  }
})();

I should also note that I've tried adding rootScope.$digest() in different places in the test, but that doesn't seem to make any difference. I thought manually triggering the digest cycle would ensure that the http post was caught and the response mocked.

Aucun commentaire:

Enregistrer un commentaire