lundi 6 juillet 2015

How to mock Angular service method which takes parameter

I'm attempting to test my Angular controllers and need to mock several services in order to do so. I'll focus on one service in this question as the rest function similarly. I use dependency injection to get ahold of playersService and use it like so in my controller:

angular.module('gameApp')
  .controller('PlayerInfoController', PlayerInfoController);

PlayerInfoController.$inject = ['$scope', '$routeParams', 'playersService'];

function PlayerInfoController($scope, $routeParams, playersService) {
  var vm = this;
  var playerId = $routeParams.playerId;

  playersService.getDetails({
    playerId: playerId
  }).$promise.then(function(details) {
    vm.details = details;
  });
}

The relevant service looks like this:

angular.module('gameApp')
  .factory('playersService', ['$resource',
    function($resource) {
      var base = '/api/players/:playererId/';
      return $resource(base, {}, {
        getDetails: {method: 'GET', url: base + 'details'}
      });
    }]);

Below is my current unit test setup which fails with the following error: TypeError: 'undefined' is not an object (evaluating 'playersService.getDetails({playerId: playerId}).$promise.then')

describe('PlayerInfoController', function() {
  var scope;
  var routeParams;
  var playersService;

  beforeEach(function() {
    var mockPlayersService = {};
    module('gameApp', function($provide) {
      $provide.value('playersService', mockPlayersService);
    });
    inject(function($q) {
      mockPlayersService.details = {
        'firstName': 'John',
        'lastName': 'Doe',
        'country': 'US'
      };

      mockPlayersService.getDetails = function(playerId) {
        var defer = $q.defer();
        defer.resolve(this.details);
        return defer.promise;
      };
    });
  });

  beforeEach(inject(function($controller, $rootScope, _$routeParams_, _playersService_) {
    scope = $rootScope.$new();
    routeParams = _$routeParams_;
    playersService = _playersService_;

    $controller('PlayerInfoController', {$scope: scope, $routeParams: routeParams, playersService: playersService});

    scope.$digest();
  }));

  it('should say 2 === 2', function() {
    expect(2).toEqual(2);
  });
});

Aucun commentaire:

Enregistrer un commentaire