web-dev-qa-db-fra.com

jasmine: le rappel asynchrone n'a pas été appelé dans le délai spécifié par jasmine.DEFAULT_TIMEOUT_INTERVAL

J'ai un service angulaire appelé 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
    };

});

J'essaie de tester ce service à l'aide de jasmin:

"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();       
    });
});

J'ai lu sur le support asynchrone dans Jasmine, mais comme je suis plutôt nouveau dans le test unitaire avec javascript, je ne pouvais pas le faire fonctionner.

Je reçois une erreur: 

Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL

et mon test prend trop de temps à exécuter (environ 5 secondes).

Quelqu'un peut-il m'aider à fournir un exemple de travail de mon code avec quelques explications?

107
Mdb

Si vous avez un argument dans votre fonction it (done dans le code ci-dessous), Jasimne tentera un appel asynchrone.

//this block signature will trigger async behavior.
it("should work", function(done){
  //...
});

//this block signature will run synchronously
it("should work", function(){
  //...
});

Le nom de l'argument done n'a pas d'importance; son existence est tout ce qui compte. J'ai rencontré ce problème avec trop de copies/pâtes.

Jasmin Support asynchrone docs note que l'argument (nommé done ci-dessus) est un rappel qui peut être appelé pour informer Jasmine du moment où une fonction asynchrone est terminée. Si vous ne l'appelez jamais, Jasmine ne saura jamais que votre test est terminé et finira par expirer.

191
mastaBlasta

En guise de solution de contournement, vous pouvez augmenter le délai d'expiration pour évaluer un rappel asynchrone Jasmine

describe('Helper', function () {
    var originalTimeout;

    beforeEach(function() {
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
    });

    afterEach(function() {
      jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });

    it('Template advance', function(doneFn) {
        $.ajax({
            url: 'public/your-end-point.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();
            }
        });
    });
});

Source: http://jasmine.github.io/2.0/introduction.html#section-42

39
gsalgadotoledo

Cette erreur peut également être provoquée en omettant d’injecter lors de l’initialisation d’un service/d’une usine ou autre. Par exemple, cela peut être jeté en faisant ceci:

var service;
beforeEach(function(_TestService_) {
    service = _TestService_;
});

Pour résoudre ce problème, enveloppez simplement la fonction avec inject afin de récupérer correctement le service:

var service;
beforeEach(inject(function(_TestService_) {
    service = _TestService_;
}));
17
Katana24
import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';

utiliser fakeAsync  

beforeEach(fakeAsync (() => {

//your code

}));



describe('Intilalize', () => {
        it('should have a defined component', fakeAsync(() => {
            createComponent();
            expect(_AddComponent.ngOnInit).toBeDefined();
        }));
    });
7
Lijo

Cette erreur a commencé pour moi de manière inattendue, sur un test qui avait toujours fonctionné. Je ne trouvais aucune suggestion susceptible de m'aider tant que je n'avais pas remarqué que mon Macbook fonctionnait lentement. J'ai remarqué que le processeur était lié à un autre processus, que j'ai tué. L'erreur asynchrone Jasmine a disparu et mes tests sont corrects encore une fois.

Ne me demande pas pourquoi, je ne sais pas. Mais dans mon cas, il semblait y avoir un manque de ressources système en faute.

4
Eric Soyke

Vous pouvez utiliser karma-jasmine plugin pour définir globalement l'intervalle de temporisation par défaut.

Ajouter cette configuration dans karma.conf.js

module.exports = function(config) {
  config.set({
    client: {
      jasmine: {
        timeoutInterval: 10000
      }
    }
  })
}
2
code.rookie

Vous obtenez également cette erreur lorsque vous attendez quelque chose dans la fonction beforeAll

describe('...', function () {

    beforeAll(function () {
        ...

        expect(element(by.css('[id="title"]')).isDisplayed()).toBe(true);
    });

    it('should successfully ...', function () {

    }
}
2
Tom Van Rossom

Fonctionne après la suppression de la référence scope et des arguments de la fonction:

"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} );
    });
});
1
Paul Sweatte

Si vous avez un argument (done) dans la fonction it, essayez de le supprimer également; il s'agit également d'un appel dans la fonction

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        
});
0
tiagor87

Comme l'a noté @mastablasta, mais aussi d'ajouter que si vous appelez l'argument 'done' ou plutôt nommez-le completed vous appelez simplement le rappel terminé () dans votre test lorsqu'il est terminé.

// this block signature will trigger async behavior.
it("should work", function(done){
  // do stuff and then call done...
  done();
});

// this block signature will run synchronously
it("should work", function(){
  //...
});
0
SoEzPz

jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;

Garder cela dans le bloc a résolu mon problème.

it('', () => {
 jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
});
0
Sai Prasad

Dans mon cas, cette erreur est due à une utilisation incorrecte de "fixture.detectChanges ()". Il semble que cette méthode soit un écouteur d'événements (asynchrone) qui ne répondra à un rappel que lorsque des modifications sont détectées. Si aucune modification n'est détectée, le rappel n'est pas appelé, ce qui entraîne une erreur de délai d'attente. J'espère que cela t'aides :)

0
A. Figueroa

Ce que j'ai fait était: ajouté/mis à jour le code suivant:

framework: 'jasmine',
jasmineNodeOpts: 
{
    // Jasmine default timeout
    defaultTimeoutInterval: 60000,
    expectationResultHandler(passed, assertion) 
    {
      // do something
    },
}
0
Zeeshan

C'est plus une observation qu'une réponse, mais cela peut aider d'autres personnes aussi frustrées que moi. 

J'ai continué à avoir cette erreur de deux tests dans ma suite. Je pensais que j'avais simplement cassé les tests avec la refactorisation que je faisais, alors après que l'annulation des modifications n'a pas fonctionné, je suis revenu au code précédent, à deux reprises (deux révisions en arrière) en pensant que cela éliminerait l'erreur. Cela n'a rien changé. J'ai poursuivi ma queue toute la journée hier et une partie de ce matin sans résoudre le problème.

J'étais frustré et j'ai vérifié le code sur un ordinateur portable ce matin. A couru toute la suite de tests (environ 180 tests), aucune erreur. Donc, les erreurs n'ont jamais été dans le code ou les tests. Je suis retourné à ma boîte de dev et je l'ai redémarré pour effacer tout ce qui pourrait avoir été en mémoire dans la mémoire. Pas de changement, mêmes erreurs sur les deux mêmes tests. J'ai donc supprimé le répertoire de ma machine et l'ai extrait. Voila! Aucune erreur.

Aucune idée de sa cause, ni de la façon de la réparer, mais supprimer le répertoire de travail et le relancer a été réparé, quoi qu'il en soit. 

J'espère que ça aide quelqu'un.

0
delliottg