then - rutas en angularjs
Error AngularJS: solicitud inesperada(no se esperan más solicitudes) (2)
Cuando realiza pruebas unitarias con AngularJS, en realidad está utilizando servicios simulados del módulo ngMock
lugar de servicios reales. En este caso, su error probablemente provenga de $httpBackend
mock, que debe estar "preparado" primero, si está esperando que las unidades probadas usen $http
para enviar solicitudes reales. (No veo tu código usando $http
ninguna parte, así que supongo que hay una parte que no se muestra aquí).
Básicamente, necesitas decirle al $httpBackend
que estás esperando una solicitud en particular usando $httpBackend.when
(o puedes usar $httpBackend.expect
, si quieres que el simulacro compruebe que la solicitud fue realmente llamada) y qué respuesta debe ser devuelto
Por lo tanto, su error no tiene nada que ver con las promesas y todo lo relacionado con las unidades de prueba que se conectan al servidor.
En mi aplicación AngularJS, tengo problemas para averiguar cómo probar la unidad y que la ejecución de una promesa de ese tipo cambia una ubicación.url. Tengo una función, inicio de sesión , que llama a un servicio, AuthenticationService . Devuelve la promesa, y la ejecución de la promesa entonces cambia la ubicación.url.
Este es el controlador AuthCtrl :
angular
.module(''bloc1App'')
.controller(''AuthCtrl'', [''$scope'', ''$http'',''$location'', ''AuthenticationService'',
function($scope, $http, $location, AuthenticationService) {
this.AuthenticationService = AuthenticationService;
var self = this;
$scope.login = function(username, password){
self.AuthenticationService
.login(username, password)
.then(function(){
$location.url(''/tasks'');
});
};
}
]);
Este es mi intento en la prueba unitaria:
describe(''Controller: AuthCtrl'', function () {
var scope,
location,
route,
q,
rootScope,
AuthCtrl;
beforeEach(module(''bloc1App''));
beforeEach(inject(function($controller, $rootScope, $location, $route, $q) {
scope = $rootScope.$new();
q = $q;
rootScope = $rootScope;
location = $location;
route = $route;
AuthCtrl = $controller(''AuthCtrl'', {
$scope: scope,
$route: route,
$location: location
});
}));
it(''login should redirect user to tasks view'', function(){
var deferred = q.defer();
spyOn(AuthCtrl.AuthenticationService, ''login'').andReturn(deferred.promise);
spyOn(location, ''url'');
scope.login(''foo'', ''foo'');
deferred.resolve();
scope.$apply();
expect(location.url).toHaveBeenCalledWith(''/tasks'');
});
});
Cuando realizo esta prueba, obtengo este error. Me sale el mismo error si uso rootScope. $ Apply () en su lugar:
Error: Unexpected request: GET views/AuthView.html
No more request expected
Cuando saco scope. $ Apply (), obtengo este error:
Expected spy url to have been called with [ ''/tasks'' ] but it was never called.
¿Alguna idea sobre cómo solucionar este problema? Esta es la primera vez que estoy probando la unidad de una promesa, y probablemente estoy conceptualmente mal entendiendo cómo hacer esto.
Gracias de antemano por su ayuda.
Tal vez sea un punto discutible responder a la pregunta casi dos años después de haberse formulado, pero la respuesta aceptada no es del todo correcta. El problema es que no estás burlándote correctamente de AuthenticationService
. Debería burlarse por completo de la funcionalidad del servicio, probar solo que el servicio ha sido llamado desde el controlador y guardar las cosas de $httpBackend
para probar el servicio en sí. Lo que quiere hacer es inyectar un servicio de AuthenticationService
falso (así como simular instancias de servicios angulares como $q
, $location
y $route
, si seguimos las mejores prácticas) en el beforeEach
, y luego declararlo en $controller
definición del $controller
También puede incluir sus espías en el bloque beforeEach
.
describe(''AuthCtrl'', function(){
var $q;
var $location;
var $controller;
var AuthenticationService;
var $route;
var deferred;
beforeEach(inject(function( _$controller_, $rootScope, _AuthenticationService_, _$q_, _$location_, _$route_){
scope = $rootScope.$new();
AuthenticationService = _AuthenticationService_;
$location = _$location_;
$route = _$route_;
$controller = _$controller_;
$q = _$q_;
deferred = $q.defer();
spyOn(AuthenticationService, ''login'').andReturnValue(deferred.promise);
spyOn($location, ''url'');
AuthCtrl = $controller(''AuthCtrl'', {
scope: scope,
AuthenticationService: AuthenticationService,
$route: $route,
$location: $location
};
}));
it(''should redirect the user on login'', function(){
deferred.resolve();
scope.$apply();
expect($location.url).toHaveBeenCalledWith(''/tasks'');
});
});
Tenga en cuenta que es importante hacer que su definición de controlador sea el último elemento en el bloque beforeEach
si está definiendo sus variables de esta manera, de lo contrario los simulacros no se crearán correctamente y los métodos de servicio se llamarán, independientemente de los espías.