233 votes

Dans mocha testing, lors de l'appel d'une fonction asynchrone, comment éviter le dépassement du délai d'attente ? Erreur : dépassement du délai d'attente de 2000 ms.

Dans mon application node, j'utilise mocha pour tester mon code. En appelant de nombreuses fonctions asynchrones avec mocha, j'obtiens une erreur de timeout ( Error: timeout of 2000ms exceeded. ). Comment puis-je résoudre ce problème ?

var module = require('../lib/myModule');
var should = require('chai').should();

describe('Testing Module', function() {

    it('Save Data', function(done) {

        this.timeout(15000);

        var data = {
            a: 'aa',
            b: 'bb'
        };

        module.save(data, function(err, res) {
            should.not.exist(err);
            done();
        });

    });

    it('Get Data By Id', function(done) {

        var id = "28ca9";

        module.get(id, function(err, res) {

            console.log(res);
            should.not.exist(err);
            done();
        });

    });

});

376voto

Andreas Hultgren Points 4235

Vous pouvez soit définir le délai d'attente lors de l'exécution de votre test :

mocha --timeout 15000

Vous pouvez également définir le délai d'attente pour chaque suite ou chaque test de manière programmatique :

describe('...', function(){
  this.timeout(15000);

  it('...', function(done){
    this.timeout(15000);
    setTimeout(done, 15000);
  });
});

Pour plus d'informations, voir le docs .

86voto

oligofren Points 2574

Je trouve que la "solution" consistant à augmenter les délais d'attente masque ce qui se passe réellement ici, à savoir que

  1. Votre code et/ou vos appels réseau sont beaucoup trop lents (ils devraient être inférieurs à 100 ms pour une bonne expérience utilisateur).
  2. Les assertions (tests) échouent et quelque chose avale les erreurs avant que Mocha ne soit capable d'agir sur elles.

Vous rencontrez généralement le #2 lorsque Mocha ne reçoit pas les erreurs d'assertion d'un callback. Ceci est causé par un autre code qui avale l'exception plus haut dans la pile. La bonne façon de traiter ce problème est de corriger le code et de ne pas avaler l'erreur. .

Quand le code externe avale vos erreurs

S'il s'agit d'une fonction de bibliothèque que vous ne pouvez pas modifier, vous devez attraper l'erreur d'assertion et la transmettre vous-même à Mocha. Pour ce faire, vous devez envelopper votre rappel d'assertion dans un bloc try/catch et transmettre toute exception au gestionnaire d'assertion.

it('should not fail', function (done) { // Pass reference here!

  i_swallow_errors(function (err, result) {
    try { // boilerplate to be able to get the assert failures
      assert.ok(true);
      assert.equal(result, 'bar');
      done();
    } catch (error) {
      done(error);
    }
  });
});

Ce modèle peut bien sûr être extrait dans une fonction utilitaire pour rendre le test un peu plus agréable à l'œil :

it('should not fail', function (done) { // Pass reference here!
    i_swallow_errors(handleError(done, function (err, result) {
        assert.equal(result, 'bar');
    }));
});

// reusable boilerplate to be able to get the assert failures
function handleError(done, fn) {
    try { 
        fn();
        done();
    } catch (error) {
        done(error);
    }
}

Accélérer les tests de réseau

A part cela, je vous suggère de suivre les conseils pour commencer à utiliser des stubs de test pour les appels réseau afin de faire passer les tests sans avoir à dépendre d'un réseau fonctionnel. En utilisant Mocha, Chai et Sinon, les tests pourraient ressembler à quelque chose comme ceci

describe('api tests normally involving network calls', function() {

    beforeEach: function () {
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = [];

        this.xhr.onCreate = function (xhr) {
            requests.push(xhr);
        };
    },

    afterEach: function () {
        this.xhr.restore();
    }

    it("should fetch comments from server", function () {
        var callback = sinon.spy();
        myLib.getCommentsFor("/some/article", callback);
        assertEquals(1, this.requests.length);

        this.requests[0].respond(200, { "Content-Type": "application/json" },
                                 '[{ "id": 12, "comment": "Hey there" }]');
        expect(callback.calledWith([{ id: 12, comment: "Hey there" }])).to.be.true;
    });

});

Voir Sinon nise docs pour plus d'informations.

26voto

user1374488 Points 23

Si vous utilisez les fonctions de flèches :

it('should do something', async () => {
  // do your testing
}).timeout(15000)

7voto

Daniel Mbeyah Points 227

Un peu tard mais quelqu'un peut utiliser ceci à l'avenir... Vous pouvez augmenter le timeout de votre test en mettant à jour scripts dans votre package.json avec ce qui suit :

"scripts": { "test": "test --timeout 10000" //Adjust to a value you need }

Exécutez vos tests en utilisant la commande test

2voto

syberkitten Points 215

Pour moi, le problème était en fait la fonction de description, qui, lorsqu'elle est fournie avec une fonction flèche, fait que mocha manque le et se comporte de manière non cohérente. (En utilisant ES6)

Comme aucune promesse n'a été rejetée, j'ai obtenu cette erreur tout le temps pour différents tests qui échouaient à l'intérieur du bloc describe.

C'est donc à ça que ça ressemble quand ça ne fonctionne pas correctement :

describe('test', () => { 
 assert(...)
})

et cela fonctionne en utilisant la fonction anonyme

describe('test', function() { 
 assert(...)
})

J'espère que cela aidera quelqu'un, ma configuration pour ce qui précède : (nodejs : 8.4.0, npm : 5.3.0, mocha : 3.3.0)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X