page navigationend change cambiar javascript angularjs mocking jasmine angularjs-service

javascript - navigationend - Inyectar un simulacro en un servicio AngularJS



router events subscribe angular 4 (7)

Además de la respuesta de John Galambos : si solo quieres burlar métodos específicos de un servicio, puedes hacerlo así:

describe(''Service: myService'', function () { var mockDependency; beforeEach(module(''myModule'')); beforeEach(module(function ($provide, myDependencyProvider) { // Get an instance of the real service, then modify specific functions mockDependency = myDependencyProvider.$get(); mockDependency.getSomething = function() { return ''mockReturnValue''; }; $provide.value(''myDependency'', mockDependency); }); it(''should return value from mock dependency'', inject(function (myService) { expect(myService.useDependency()).toBe(''mockReturnValue''); })); });

Tengo un servicio AngularJS escrito y me gustaría probarlo en una unidad.

angular.module(''myServiceProvider'', [''fooServiceProvider'', ''barServiceProvider'']). factory(''myService'', function ($http, fooService, barService) { this.something = function() { // Do something with the injected services }; return this; });

Mi archivo app.js tiene estos registrados:

angular .module(''myApp'', [''fooServiceProvider'',''barServiceProvider'',''myServiceProvider''] )

Puedo probar que DI está funcionando como tal:

describe("Using the DI framework", function() { beforeEach(module(''fooServiceProvider'')); beforeEach(module(''barServiceProvider'')); beforeEach(module(''myServiceProvder'')); var service; beforeEach(inject(function(fooService, barService, myService) { service=myService; })); it("can be instantiated", function() { expect(service).not.toBeNull(); }); });

Esto demostró que el servicio puede ser creado por el marco DI, sin embargo, luego quiero probar el servicio en una sola unidad, lo que significa burlarse de los objetos inyectados.

¿Cómo voy a hacer esto?

Intenté poner mis objetos simulados en el módulo, por ej.

beforeEach(module(mockNavigationService));

y reescribiendo la definición del servicio como:

function MyService(http, fooService, barService) { this.somthing = function() { // Do something with the injected services }; }); angular.module(''myServiceProvider'', [''fooServiceProvider'', ''barServiceProvider'']). factory(''myService'', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })

Pero el último parece detener el servicio creado por el DI como todos.

¿Alguien sabe cómo puedo burlarme de los servicios inyectados para las pruebas de mi unidad?

Gracias

David


Otra opción para ayudar a que las dependencias de burla sean más fáciles en Angular y Jasmine es usar QuickMock. Se puede encontrar en GitHub y le permite crear simulaciones simples de una manera reutilizable. Puedes clonarlo desde GitHub a través del siguiente enlace. El README es bastante auto explicativo, pero es de esperar que pueda ayudar a otros en el futuro.

https://github.com/tennisgent/QuickMock

describe(''NotificationService'', function () { var notificationService; beforeEach(function(){ notificationService = QuickMock({ providerName: ''NotificationService'', // the provider we wish to test moduleName: ''QuickMockDemo'', // the module that contains our provider mockModules: [''QuickMockDemoMocks''] // module(s) that contains mocks for our provider''s dependencies }); }); ....

Gestiona automáticamente todas las plantillas mencionadas anteriormente, por lo que no tiene que escribir todo ese código de inyección simulada en cada prueba. Espero que ayude.


Por la forma en que lo miro, no hay necesidad de burlarse de los servicios ellos mismos. Simplemente simula las funciones en el servicio. De esta manera, puede tener angular inyectar sus servicios reales como lo hace a lo largo de la aplicación. Luego, simula las funciones en el servicio según sea necesario usando la función spyOn de Jasmine.

Ahora, si el servicio en sí es una función, y no un objeto con el que puede usar spyOn , hay otra manera de hacerlo. Necesitaba hacer esto, y encontré algo que funciona bastante bien para mí. Consulte ¿Cómo se burla del servicio angular que es una función?


Puedes inyectar burlas en tu servicio usando $provide .

Si tiene el siguiente servicio con una dependencia que tiene un método llamado getSomething:

angular.module(''myModule'', []) .factory(''myService'', function (myDependency) { return { useDependency: function () { return myDependency.getSomething(); } }; });

Puede inyectar una versión simulada de myDependency de la siguiente manera:

describe(''Service: myService'', function () { var mockDependency; beforeEach(module(''myModule'')); beforeEach(function () { mockDependency = { getSomething: function () { return ''mockReturnValue''; } }; module(function ($provide) { $provide.value(''myDependency'', mockDependency); }); }); it(''should return value from mock dependency'', inject(function (myService) { expect(myService.useDependency()).toBe(''mockReturnValue''); })); });

Tenga en cuenta que debido a la llamada a $provide.value realidad no necesita inyectar explícitamente myDependency en ningún lugar. Sucede bajo la capucha durante la inyección de myService. Al configurar MockDependency aquí, podría ser tan fácil como un espía.

Gracias a loyalBrown por el enlace a ese gran video .


Recientemente lancé ngImprovedTesting que debería facilitar las pruebas simuladas en AngularJS.

Para probar ''myService'' (desde el módulo "myApp") con sus dependencias fooService y barService burladas, puede hacer lo siguiente en su prueba Jasmine:

beforeEach(ModuleBuilder .forModule(''myApp'') .serviceWithMocksFor(''myService'', ''fooService'', ''barService'') .build());

Para obtener más información sobre ngImprovedTesting, consulte su publicación introductoria del blog: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/


Sé que esta es una pregunta antigua, pero hay otra manera más fácil, puede crear simulacro y deshabilitar el original inyectado en una función, se puede hacer mediante el uso de spyOn en todos los métodos. ver el código a continuación.

var mockInjectedProvider; beforeEach(function () { module(''myModule''); }); beforeEach(inject(function (_injected_) { mockInjectedProvider = mock(_injected_); }); beforeEach(inject(function (_base_) { baseProvider = _base_; })); it("injectedProvider should be mocked", function () { mockInjectedProvider.myFunc.andReturn(''testvalue''); var resultFromMockedProvider = baseProvider.executeMyFuncFromInjected(); expect(resultFromMockedProvider).toEqual(''testvalue''); }); //mock all service methods function mock(angularServiceToMock) { for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) { spyOn(angularServiceToMock,Object.getOwnPropertyNames(angularServiceToMock)[i]); } return angularServiceToMock; }


Si su controlador está escrito para tomar una dependencia como esta:

app.controller("SomeController", ["$scope", "someDependency", function ($scope, someDependency) { someDependency.someFunction(); }]);

entonces puedes hacer una falsa someDependency en una prueba de jazmín como esta:

describe("Some Controller", function () { beforeEach(module("app")); it("should call someMethod on someDependency", inject(function ($rootScope, $controller) { // make a fake SomeDependency object var someDependency = { someFunction: function () { } }; spyOn(someDependency, "someFunction"); // this instantiates SomeController, using the passed in object to resolve dependencies controller("SomeController", { $scope: scope, someDependency: someDependency }); expect(someDependency.someFunction).toHaveBeenCalled(); })); });