Как издеваться над угловым сервисным методом, который принимает параметр

0

Я пытаюсь протестировать свои угловые контроллеры и нужно издеваться над несколькими услугами, чтобы сделать это. Я сосредоточусь на одной службе в этом вопросе, так как функция останова аналогична. Я использую инъекцию зависимостей, чтобы получить поддержку playersService и использовать его в моем контроллере:

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;
  });
}

Соответствующая услуга выглядит так:

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

Ниже приведена моя текущая тестовая установка, которая не выполняется со следующей ошибкой: 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);
  });
});
Теги:
unit-testing
promise
jasmine

1 ответ

2
Лучший ответ

playersService.getDetails обычно возвращает относительно пустой объект с свойством $ prom, после завершения вызова этот объект заполняется результатом.

Ваш mockPlayersService.getDetails должен вернуть похожий объект, поэтому что-то вроде этого должно делать:

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

И в качестве примечания, в соответствии с угловыми документами, вы обычно используете свою службу, как это (второй параметр может быть функцией для вызова успеха вместо использования $ обещания).

playersService.getDetails({
  playerId: playerId
}, function(details) {
  vm.details = details;
});

Это также потребовало бы, чтобы вы изменили ваш макет службы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню