unit test run karma e2e unit-testing angularjs jasmine

unit testing - test - ¿Cómo puedo probar un controlador con propiedades de resolución en AngularJS?



test unit angular 4 (4)

¿Cómo se puede probar un controlador con propiedades de resolución? Se produce un error: Proveedor desconocido: InitProvider, durante la prueba, de manera comprensible. ¿Cómo puedo probarlo?

Utilizo la propiedad init en la configuración de ruta para cargar datos y pasarlos al controlador en la instanciación del controlador para que la ruta no cambie antes de que se carguen los datos.

$routeProvider .when(''/topic/:topic_id/content/:content_id'', { templateUrl: ''views/content.html'', controller: ''ContentCtrl'', resolve: { init: ContentCtrl.init } });

¿Es el patrón completamente incorrecto en primer lugar?

''use strict''; var ContentCtrl = [''$scope'', ''$location'', ''$routeParams'', ''init'', function ($scope, $location, $routeParams, init) { $scope.contents = init.contents; }]; ContentCtrl.init = [''$q'', ''app_config'', ''$log'', ''$timeout'', function ($q, app_config, $log, $timeout) { var defer = $q.defer(); $log.log("ContentCtrl loading.."); $timeout(function() { defer.resolve({contents: [ {message: ''Hello!''} ]}); $log.log("ContentCtrl loaded."); }, 2000); return defer.promise; }]; angular.module(''studentportalenApp'').controller(''ContentCtrl'', ContentCtrl);

Quiero encapsular todo el controlador dentro de .controler(''ContentCtrl'', function() { ... }) , pero aún tengo que descubrir cómo se hace esto correctamente para que el inicio esté disponible en la configuración de la ruta.


A prueba unitaria de valores resueltos de una ruta:

var resolutionObject = $ injector.invoke ($ route.current. $$ route.resolve.testedObject);


Finalmente, se resolvió convirtiendo todo a servicios, como sugirió charlietfl.

Ejemplo:

Configuración de ruta:

//This helper injects a function with the service //defined in the initMethod string and returns services.prepare() var interceptWith = function(initMethod) { return [initMethod, function(m) { return m.prepare(); }]; } $routeProvider .when(''/foobar/'', { templateUrl: ''foobar.html'', controller: ''FoobarCtrl'', resolve: { init: interceptWith(''FoobarCtrlInit'') } });

La definición del controlador foobar:

angular.module(''fooApp'').controller(''FoobarCtrl'', [''$scope'', ''init'', function ($scope, init) { $scope.data = init.data; }]) .service(''FoobarCtrlInit'', [''$q'', ''$timeout'', function ($q, $timeout) { var _prepare = function() { var deferred = $q.defer(); //Fake async loading of data $timeout(function() { deferred.resolve({data: [''A'',''B'',''C'']}); }, 1000); return deferred.promise; } return { prepare: _prepare } }]);

Para probar esto, uno podría hacer esto:

''use strict''; describe(''Controller: FoobarCtrl'', function() { // load the controller''s module beforeEach(module(''fooApp'')); var FoobarCtrl, scope; // Initialize the controller and a mock scope beforeEach(inject(function($controller) { scope = {}; CourseCtrl = $controller(''FoobarCtrl'', { $scope: scope, init: {data: [''Testdata A'', ''B'', ''C'']} }); })); it(''should attach a list of data to the scope'', function() { expect(scope.data.length).toBe(3); }); });


Me encontré con lo mismo aquí. Lo resolví utilizando el enfoque aquí: https://groups.google.com/forum/?fromgroups=#!topic/angular/LzXm-9nwkjY .

Básicamente, me burlé de los datos que normalmente se enviarían utilizando una variable simple y los agregué al controlador en la prueba. En tu caso supongo que se vería algo así como:

var initData = { contents: [{message: ''Hello!''}] }; $controller("ContentCtrl", { $scope: ..., init: initData });


Tuve el mismo error en Karma al usar la resolución en $ routeProvider, la arreglé probando mi resolución en la prueba de la unidad para app.js, como esto:

describe("myApp", function() { beforeEach(module(''myApp'')); it(''should resolve initial values for my Controller'', inject(function( $route ) { expect($route.routes[''/''].resolve.init).toBeDefined; //or whatever test you want })); });

Y luego me burlé del valor en la prueba para mi controlador, como este dentro de la descripción para el controlador:

//mock out the resolved values to isolate controller code beforeEach(module(function($provide) { $provide.value(''init'', function() { return ''whatever data you need to mock''; });