angularjs - jazmín: la devolución de llamada asíncrona no se invocó dentro del tiempo de espera especificado por jasmine.DEFAULT_TIMEOUT_INTERVAL
unit-testing debugging (9)
Tengo un servicio angular llamado requestNotificationChannel
:
app.factory("requestNotificationChannel", function($rootScope) {
var _DELETE_MESSAGE_ = "_DELETE_MESSAGE_";
function deleteMessage(id, index) {
$rootScope.$broadcast(_DELETE_MESSAGE_, { id: id, index: index });
};
return {
deleteMessage: deleteMessage
};
});
Estoy intentando probar la unidad de este servicio usando jazmín:
"use strict";
describe("Request Notification Channel", function() {
var requestNotificationChannel, rootScope, scope;
beforeEach(function(_requestNotificationChannel_) {
module("messageAppModule");
inject(function($injector, _requestNotificationChannel_) {
rootScope = $injector.get("$rootScope");
scope = rootScope.$new();
requestNotificationChannel = _requestNotificationChannel_;
})
spyOn(rootScope, ''$broadcast'');
});
it("should broadcast delete message notification", function(done) {
requestNotificationChannel.deleteMessage(1, 4);
expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4 });
done();
});
});
Leí sobre el soporte asincrónico en Jasmine, pero como soy bastante nuevo en pruebas unitarias con javascript, no pude hacerlo funcionar.
Estoy recibiendo un error:
Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL
y mi prueba está tardando demasiado en ejecutarse (aproximadamente 5s).
¿Alguien puede ayudarme a dar un ejemplo de trabajo de mi código con alguna explicación?
¡También obtiene este error cuando espera algo en la función beforeAll
!
describe(''...'', function () {
beforeAll(function () {
...
expect(element(by.css(''[id="title"]'')).isDisplayed()).toBe(true);
});
it(''should successfully ...'', function () {
}
}
Debes aumentar el límite de tiempo de espera para evaluar la devolución de llamada sync jazmín
describe(''Helper'', function () {
var originalTimeout;
beforeEach(function() {
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
});
afterEach(function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
it(''template advance'', function(doneFn) {
$.ajax({
url: ''public/gustavo-salgado.mock.json'',
dataType: ''json'',
success: function (data, response) {
// Here your expected using data
expect(1).toBe(1)
doneFn();
},
error: function (data, response) {
// Here your expected using data
expect(1).toBe(1)
doneFn();
}
});
});
});
Fuente: http://jasmine.github.io/2.0/introduction.html#section-42
En mi caso, este error fue causado por el uso inapropiado de "fixture.detectChanges ()" Parece que este método es un detector de eventos (async) que solo responderá una devolución de llamada cuando se detecten cambios. Si no se detectan cambios, no invocará la devolución de llamada, lo que ocasionará un error de tiempo de espera. Espero que esto ayude :)
Este error comenzó de la nada para mí, en una prueba que siempre había funcionado. No pude encontrar ninguna sugerencia que me ayudara hasta que noté que mi Macbook funcionaba lentamente. Noté que la CPU estaba vinculada a otro proceso, que maté. El error asincrónico de Jasmine desapareció y mis pruebas están bien una vez más.
No me preguntes por qué, no sé. Pero en mi circunstancia, parecía ser una falta de recursos del sistema en falta.
Este error también puede ser causado al dejar de inyectar al inicializar un servicio / fábrica o lo que sea. Por ejemplo, se puede lanzar haciendo esto:
var service;
beforeEach(function(_TestService_) {
service = _TestService_;
});
Para solucionarlo simplemente ajuste la función con Inject para recuperar el servicio correctamente:
var service;
beforeEach(inject(function(_TestService_) {
service = _TestService_;
}));
Funciona después de eliminar la referencia de scope
y los argumentos de la función:
"use strict";
describe("Request Notification Channel", function() {
var requestNotificationChannel, rootScope;
beforeEach(function() {
module("messageAppModule");
inject(function($injector, _requestNotificationChannel_) {
rootScope = $injector.get("$rootScope");
requestNotificationChannel = _requestNotificationChannel_;
})
spyOn(rootScope, "$broadcast");
});
it("should broadcast delete message notification with provided params", function() {
requestNotificationChannel.deleteMessage(1, 4);
expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4} );
});
});
Tener una discusión en su función hará que intente una llamada asíncrona.
//this block signature will trigger async behavior.
it("should work", function(done){
//...
});
//this block signature will run synchronously
it("should work", function(){
//...
});
No importa el nombre del argumento done
, su existencia es lo único que importa. Me encontré con este problema de demasiada copia / pasta.
El Soporte Asíncrono de Jasmin nota que el argumento (mencionado anteriormente) es una devolución de llamada que se puede invocar para informar a Jasmine cuando se completa una función asincrónica. Si nunca lo llamas, Jasmine nunca sabrá que tu prueba ya está hecha y eventualmente terminará.
import { fakeAsync, ComponentFixture, TestBed } from ''@angular/core/testing'';
usar fakeAsync
beforeEach(fakeAsync (() => {
//your code
}));
describe(''Intilalize'', () => {
it(''should have a defined component'', fakeAsync(() => {
createComponent();
expect(_AddComponent.ngOnInit).toBeDefined();
}));
});
it("should broadcast delete message notification", function(/*done -> YOU SHOULD REMOVE IT */) {
requestNotificationChannel.deleteMessage(1, 4);
expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4 });
// done(); -> YOU SHOULD REMOVE IT
});