unitarios unitarias tutorial test pruebas karma español unit-testing angularjs dependency-injection jasmine

unit-testing - tutorial - pruebas unitarias angular 6



¿Por qué $ también está disponible en la función ''angular.mock.module'', y $ q solo está disponible en la función ''angular.mock.inject''? (2)

Me estoy burlando de un servicio para una prueba de unidad AngularJS. Estoy usando el servicio $provide para reemplazar el servicio "real" con el mocked out (un script de plunker disponible):

describe(''My Controller'', function () { var $scope; var $provide; beforeEach(angular.mock.module(''myApp'')); beforeEach(angular.mock.module(function (_$provide_) { $provide = _$provide_; })); beforeEach(angular.mock.inject(function($rootScope, $controller, $q){ var mockMyService = { getAll : function() { var deferred = $q.defer(); deferred.resolve([ { itemText: "Foo" }, { itemText: "Bar" } ]); return deferred.promise; } }; $provide.value(''myService'', mockMyService); $scope = $rootScope.$new(); $controller(''MyCtrl'', { $scope: $scope }); $rootScope.$apply(); })); it(''Has two items defined'', function () { expect($scope.items.length).toEqual(2); }); });

Esto funciona bien. Sin embargo, no me gusta el hecho de que estoy usando una función angular.mock.module simplemente para dar una referencia al servicio $provide angular.mock.inject que luego se usa en la función angular.mock.inject continuación. Pero si agrego $provide un parámetro a la función angular.mock.inject directamente en su lugar, obtengo un error de "proveedor desconocido".

Se me ocurre que podría poner todo el código de burla en la función angular.mock.module . Pero luego tengo un problema similar con la referencia $q , que necesito ya que mi servicio simulado tiene que devolver una promesa.

En otras palabras, si agrego un parámetro $q a la función angular.mock.module , también obtengo un error de "proveedor desconocido".

¿Hay alguna manera de simplificar esto? Obviamente, lo que tengo funciona, pero no se siente del todo bien, de alguna manera. Creo que no entiendo por qué algunos proveedores están disponibles en funciones de inject y otros están disponibles en funciones de module .


Esto me funcionó cuando tuve que envolver un servicio que usaba $q y parece bastante limpio:

var _ServiceToTest_; beforeEach(function () { module(''module.being.tested''); module(function ($provide) { $provide.factory(''ServiceToMock'', function ($q, $rootScope) { var service = ...; // use $q et al to heart''s content return service; }); }); inject(function (_ServiceToTest_) { ServiceToTest = _ServiceToTest_; }); }); it(''...'', function () { /* code using ServiceToTest */ });

El truco consistía en usar $provide.factory lugar de $provide.value .


No puede usar $provide dentro de la función de inject porque el primero registra a los proveedores para que los use. Echar un vistazo:

describe(''...'', function() { beforeEach(function() { module(function($provide) { $provide.constant(''someValue'', ''foobar''); }); inject(function(someValue) { var value = someValue; // will be ''foobar''; }); }); });

Aunque puedes escribir tu prueba de esta manera:

describe(''...'', function() { var serviceMock; beforeEach(function() { serviceMock = { someMethod: function() { ... } }; module(function($provide) { $provide.value(''service'', serviceMock); }); inject(function(service) { ... }); }); });

De hecho, ni siquiera necesita implementar el servicio simulado antes de inyectarlo con $provide :

beforeEach(function() { serviceMock = {}; module(function($provide) { $provide.value(''service'', serviceMock); }); inject(function(service) { ... }); }); it(''tests something'', function() { // Arrange serviceMock.someMethod = function() { ... } // Act // does something // Assert expect(...).toBe(...); });

Aquí hay un script de Plunker que ilustra la mayoría de los anteriores.