How do I mock the result of a promise in an AngularJS unit test?

Shamoon

My CompanyService is:

angular.module('mean').service('CompanyService', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) {
  var company = this;
  var initializedDeferred = $q.defer();

  company.company_data = {}
  company.initialized = initializedDeferred.promise;

  company.getCompany = function() {
    return company.company_data;
  }

  company.get = function (company_id) {
    return $http({
      url: '/api/v1/company/' + company_id,
      method: 'GET',
      headers: {
        api_key: $rootScope.api_key
      }
    }).success(function(response) {
      if(response.status === 'ok') {
        company.company_data = response.company;
        initializedDeferred.resolve();
      } else {
        alert('TBD: Need fail case');
      }
    });
  };
}]);

My controller is:

angular.module('mean').controller('LocationController', ['$scope', '$location', '$rootScope', 'LocationService', 'UserService', 'CompanyService', '$modal', '$routeParams', function ($scope, $location, $rootScope, LocationService, UserService, CompanyService, $modal, $routeParams) {
  $rootScope.menuItem = 'locations';
  $scope.contentTemplate = '/views/location/index.html';
  $scope.locations = [];
  $scope.current_location = null;
  $scope.newLocation = {};
  $scope.location_parent_id = $routeParams.location_parent_id;

  $scope.index = function() {
    CompanyService.initialized.then(function() {
      $scope.test = 'a';
      var company_id = CompanyService.getCompany()._id;
      LocationService.list(company_id, $routeParams.location_parent_id).then(function(response) {
        if(response.data.status === 'ok') {
          $scope.locations = response.data.locations;
          $scope.current_location = response.data.location || null;
        }
      });
    });
  }

  $scope.addLocationModal = function() {
    $scope.location_types = ['warehouse', 'section', 'row', 'shelf', 'bin'];
    $modal({
      scope: $scope,
      template: '/views/location/addLocationModal.html',
      show: true,
      animation: 'am-fade-and-scale'
    });
  }

  $scope.createLocation = function() {
    $scope.newLocation.company_id = CompanyService.getCompany()._id;
    LocationService.create($scope.newLocation).then(function(response) {
      if(response.data.status === 'ok') {
        $scope.$hide();
      } else {
        alert('TBD');
      }
    });
  }

}]);

My test is:

(function() {
  describe('LocationController', function() {
    var $scope, $location, $rootScope, $modal, deferred, CompanyService, createController;

    beforeEach(module('mean'));

    beforeEach(inject(function($injector) {
      $location = $injector.get('$location');
      $rootScope = $injector.get('$rootScope');
      $modal = $injector.get('$modal');
      $scope = $rootScope.$new();

      var $controller = $injector.get('$controller');

      var $q = $injector.get('$q');

      var params = {
        '$scope': $scope,
        CompanyService: jasmine.createSpyObj('CompanyService', ['initialized'])
      }

      params.CompanyService.initialized.andCallFake(function () {
        deferred = $q.defer();
        return deferred.promise;
      });


      createController = function() {
        return $controller('LocationController', params);
      };
    }));

    it('should instantiate initial variables at the top level', function() {
      var controller = createController();

      $location.path('/company/locations');
      expect($location.path()).toBe('/company/locations');
      expect($rootScope.menuItem).toBe('locations');
      expect($scope.contentTemplate).toBe('/views/location/index.html');
      expect($scope.locations.length).toEqual(0);
      expect($scope.current_location).toBeNull();
      expect($scope.newLocation).toBeDefined();
      expect($scope.location_parent_id).not.toBeDefined();
    });

    it('should list all locations for this company', function() {
      var controller = createController();
      deferred.resolve();
      $scope.index();

      expect($scope.test).toBe('a');
    });
  });
})();

But, the resolve isn't working. I get this error: TypeError: 'undefined' is not an object (evaluating 'deferred.resolve')

Any help?

Beyers

In your tests you create your deferred object using the fake CompanyService.initialized function. However this function is only called when you call $scope.index();, which is executed after your deferred.resolve(); line. The following should work:

it('should list all locations for this company', function() {
  var controller = createController();
  $scope.index();   // Should in turn call the fake CompanyService.initialized function that creates deferred
  deferred.resolve();
  $scope.$apply();  // Fire $digest cycle to dispatch promises.

  expect($scope.test).toBe('a');
});

Update

Jasmine doesn't support spying on properties that are not functions. So your spy setup is invalid as CompanyService.initialized is an object and not a function, so your andCallFake wont work. A workaround is to introduce a getter function inside your CompanyServicee.g:

company.isInitialized(){ return company.initialized; }

And then inside your controller use this getter function instead:

$scope.index = function() {
  CompanyService.isInitialized().then(function() {
    $scope.test = 'a';
    // Removed for brevity
  });
}

And finally update your test code initialization:

var params = {
  '$scope': $scope,
  CompanyService: jasmine.createSpyObj('CompanyService', ['isInitialized'])
}
params.CompanyService.isInitialized.andCallFake(function () {
  deferred = $q.defer();
  return deferred.promise;
});

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How do I mock the result of a promise in an AngularJS unit test?

From Java

How do I mock a service that returns promise in AngularJS Jasmine unit test?

From Dev

How do I resolve a promise in an AngularJS unit test

From Dev

How do I unit test an AngularJS controller that relies on a promise?

From Dev

How do I mock the result in a $http.get promise when testing my AngularJS controller?

From Dev

How do I mock a class in a Python unit test?

From Dev

How do i mock UserManager and RoleManager for unit test

From Dev

how to mock $window to unit test AngularJS service?

From Dev

How do I fail a Node unit test on the catch of a Promise?

From Dev

How to unit test AngularJS $promise.then

From Dev

How do I mock $http in AngularJS service Jasmine test?

From Dev

How do I trigger a keyup/keydown event in an angularjs unit test?

From Dev

How do I trigger a mousemove event in an angularjs unit test

From Dev

Unit Test Mock Controller, C# Do I need to Mock HTTPContext? What methods do I mock?

From Dev

How to mock $window.location.replace in AngularJS unit test?

From Dev

How to mock an event like 'keypress' or 'keydown' in an AngularJS unit test?

From Dev

how can I parse this result in angularjs promise

From Dev

How do I mock controller context in my unit test so that my partial view to string function works?

From Dev

How do I mock controller context in my unit test so that my partial view to string function works?

From Dev

How do I mock the @Attribute decorator string provider in an ng2 unit test?

From Dev

How do I mock a factory that returns a promise in angularJs 1.x

From Dev

How to unit test an angularjs promise chain using $httpBackend

From Dev

How can i mock underscorejs in unit testing? [angularjs]

From Dev

How to mock springSecurityService in an unit test

From Dev

How to mock this unit test in Python?

From Dev

How do I write a unit test to verify that a function sorts its result?

From Dev

Correct way to mock an AngularJS Service in a unit test?

From Dev

AngularJS override (mock) services for unit test

From Dev

angularjs unit test karma with jasmine mock dilemma

Related Related

  1. 1

    How do I mock the result of a promise in an AngularJS unit test?

  2. 2

    How do I mock a service that returns promise in AngularJS Jasmine unit test?

  3. 3

    How do I resolve a promise in an AngularJS unit test

  4. 4

    How do I unit test an AngularJS controller that relies on a promise?

  5. 5

    How do I mock the result in a $http.get promise when testing my AngularJS controller?

  6. 6

    How do I mock a class in a Python unit test?

  7. 7

    How do i mock UserManager and RoleManager for unit test

  8. 8

    how to mock $window to unit test AngularJS service?

  9. 9

    How do I fail a Node unit test on the catch of a Promise?

  10. 10

    How to unit test AngularJS $promise.then

  11. 11

    How do I mock $http in AngularJS service Jasmine test?

  12. 12

    How do I trigger a keyup/keydown event in an angularjs unit test?

  13. 13

    How do I trigger a mousemove event in an angularjs unit test

  14. 14

    Unit Test Mock Controller, C# Do I need to Mock HTTPContext? What methods do I mock?

  15. 15

    How to mock $window.location.replace in AngularJS unit test?

  16. 16

    How to mock an event like 'keypress' or 'keydown' in an AngularJS unit test?

  17. 17

    how can I parse this result in angularjs promise

  18. 18

    How do I mock controller context in my unit test so that my partial view to string function works?

  19. 19

    How do I mock controller context in my unit test so that my partial view to string function works?

  20. 20

    How do I mock the @Attribute decorator string provider in an ng2 unit test?

  21. 21

    How do I mock a factory that returns a promise in angularJs 1.x

  22. 22

    How to unit test an angularjs promise chain using $httpBackend

  23. 23

    How can i mock underscorejs in unit testing? [angularjs]

  24. 24

    How to mock springSecurityService in an unit test

  25. 25

    How to mock this unit test in Python?

  26. 26

    How do I write a unit test to verify that a function sorts its result?

  27. 27

    Correct way to mock an AngularJS Service in a unit test?

  28. 28

    AngularJS override (mock) services for unit test

  29. 29

    angularjs unit test karma with jasmine mock dilemma

HotTag

Archive