Я пытаюсь протестировать свои угловые контроллеры и нужно издеваться над несколькими услугами, чтобы сделать это. Я сосредоточусь на одной службе в этом вопросе, так как функция останова аналогична. Я использую инъекцию зависимостей, чтобы получить поддержку 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);
});
});
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;
});
Это также потребовало бы, чтобы вы изменили ваш макет службы.