unit testing - sref - Prueba unitaria de ui-router: después de $ state.transitionTo() no puede obtener $ state.current para contener el estado actual
ui router nested views (2)
Estoy tratando de escribir la prueba de unidad para el estado del ui-enrutador y no puedo hacer que funcione para que $state.current
contenga un estado correcto dentro del controlador después de llamar a $state.transitionTo()
dentro de la prueba.
Esto funciona en el navegador (donde ui-router
llama internamente a transitionTo
), pero no en pruebas unitarias (usando Karma), donde lo llamo explícitamente.
Aquí está el código para el controlador:
angular.module( ''ngBoilerplate.about'', [
''ui.router''
])
.config(function config( $stateProvider ) {
$stateProvider.state( ''about'', {
url: ''/about'',
views: {
"main": {
controller: ''AboutCtrl'',
templateUrl: ''about/about.tpl.html''
}
},
data: {
title: "About"
}
});
})
.controller( ''AboutCtrl'', function AboutCtrl( $scope, $state ) {
console.log($state.get(''about''));
console.log($state.current);
$scope.title = $state.current.data.title;
})
;
Y aquí está el código de prueba (Jasmine) en about.spec.js
:
describe( ''AboutCtrl'', function() {
var $scope, createController;
beforeEach( module( ''ngBoilerplate.about'' ) );
beforeEach( inject( function( $controller, $rootScope, $state, $stateParams) {
$scope = $rootScope.$new();
createController = function() {
$state.transitionTo(''about'', {});
$rootScope.$digest();
return $controller( ''AboutCtrl'', { $scope: $scope, $state: $state });
};
}));
it( ''should have title for about set'', inject( function() {
var controller = createController();
expect($scope.title).toEqual(''About'');
}));
});
Esto produce los resultados:
LOG: Object{url: ''/about'', views: Object{main: Object{controller: ..., templateUrl: ...}}, data: Object{title: ''About1''}, name: ''about''}
LOG: Object{name: '''', url: ''^'', views: null, abstract: true}
Chrome 29.0.1547 (Linux) AboutCtrl should have title for about set FAILED
TypeError: Cannot read property ''title'' of undefined
Lo que muestra que el estado está siendo ingresado OK, pero no cambia por alguna razón, permanece en un estado aproximadamente inicializado. De nuevo: este código cuando se invoca en un entorno de aplicación real muestra el $state.current
correctamente llenado que tiene todos los datos, etc.
He visto las pruebas de ui-router
y parece que hacen exactamente lo mismo ( $q.flush()
es un $rootScope.$digest()
decorado), así que supongo que debería funcionar.
¿Algún consejo? (Soy un poco novato con todo lo angular hasta el momento :)
¿Ha considerado usar $rootScope.$apply()
lugar de $rootScope.$digest()
en el método createController
?
Recuerde, el enrutador ui inicializará su controlador e inyectará el objeto de alcance en él, mientras que en esta prueba, instanciará su propio controlador pasando su propio objeto de alcance. Su controlador no es el mismo que el que creó el enrutador ui y, por lo tanto, sus objetos de alcance también son referencias diferentes.
Supongo que si necesita "probar la unidad" de un ui-router, entonces pruebe solo los parámetros de estado, pero no los objetos dentro del controlador. Si necesita probar objetos con ámbito, cree una prueba unitaria para el controlador.