Ответ 1
Я знаю две стратегии для издевки службы с несколькими вариантами синтаксиса, как и все в Angular... Вы можете просто добавить литерал объекта в объявление контроллера или создать собственные службы и добавить их в модуль используя $provider:
Если служба - это всего лишь оболочка некоторого уровня данных или API, вы можете издеваться над ее функциональностью с литеральным объектом и вводить, если это правильно в конструкторе контроллера, следуя синтаксису примера, это можно сделать следующим образом:
var currentAuth;
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
currentAuth = {uid: 1, name: juan, getFriends: function() { ... }};
controller = $controller('TestableCtrl', {'$scope': $scope, 'currentAuth': currentAuth });
}));
В этом случае "currentAuth" - это служба, которая предоставляет текущему зарегистрированному пользователю в приложении.
Это допустимо только в том случае, если вам не нужно вводить какую-либо услугу в функции, определенные в объекте. Это было бы эквивалентно созданию службы стоимости и ее ввода в модуль. Если методам внутри издевающегося сервиса нужна какая-либо услуга, вам придется создать factory или службу, добавить эту службу в модуль и затем ввести ее как любую другую настраиваемую службу. См. Этот пример, который я использую для издевательства службы аутентификации с угловым огнем:
var $controller, $rootScope, $scope, $location, Auth;
beforeEach(function(){
module('planner.login');
module(function($provide){
$provide.factory('Auth', function($q){
return {
$signInWithEmailAndPassword: function(email, pass) {
return $q.reject({error: 'ERROR'});
}
};
});
return null;
});
});
beforeEach(function(){
inject(function($controller, $rootScope, _Auth_) {
$scope = $rootScope.$new();
Auth = _Auth_;
$controller("TestableCtrl", {
$scope: $scope,
Auth: Auth,
$stateParams: {}
});
});
});
В этом примере я создаю новый factory, который использует службу $q для возврата обещания angular (это не требовало тестирования в Chrome, но PhantomJS не имеет спецификации Promise). Обратите внимание, что для этого вам нужно два beforeEach, один для добавления провайдера в модуль, а другой - для ввода провайдера в контроллер.
Какой из них использовать, зависит от того, что вы хотите проверить, и насколько глубоко вам нужно подражать оригинальному поведению службы. В вашем случае с uibmodal вам, вероятно, нужно вызвать ".open" в какой-то момент и шпион, который был вызван, но вам нужно только создать объект с этим свойством и шпионить за свойством объекта для этого. Поэтому первого подхода должно быть достаточно.
Итак, ваш код должен выглядеть примерно так:
describe("Controllers", function() {
beforeEach(module("moduleName"));
describe("Jasmine testableController", function () {
var scope,
controller,
uibModal;
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
uibModal = { open: function() { return 'Whatever'; } }
controller = $controller('testableController', { $scope: scope, $uibModal: uibModal });
}));
it('should set the page title as "Welcome"', function () {
expect(scope.title).toBe('Welcome');
// you will probably do something like this at some point to verify
// that the modal gets opened on click or following any other action:
// var spy = spyOn(uibModal, 'open');
// expect(spy).toHaveBeenCalled();
});
});
});
Я надеюсь, что это поможет, пожалуйста, скажите мне, если что-то неясно, я также изучаю тестирование приложений AngularJS и хотел бы знать, помогает ли это с помощью AngularUI.