В тестировании mocha при вызове асинхронной функции как избежать ошибки тайм-аута: превышен тайм-аут 2000 МС


в моем узле приложения я использую мокко, чтобы проверить мой код. При вызове многих асинхронных функций с помощью mocha, я получаю ошибку тайм-аута (Error: timeout of 2000ms exceeded.). Как я могу решить эту проблему?

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

    });

});
4 165

4 ответа:

вы можете либо установить тайм-аут при запуске теста:

mocha --timeout 15000

или вы можете установить тайм-аут для каждого набора или каждого теста программно:

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

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

для получения дополнительной информации см. docs.

Я считаю, что "решение" просто увеличить тайм-ауты скрывает то, что действительно происходит здесь, что либо

  1. ваш код и / или сетевые вызовы слишком медленные (должно быть менее 100 мс для хорошего пользовательского опыта)
  2. утверждения (тесты) терпят неудачу, и что-то проглатывает ошибки, прежде чем Мокко сможет действовать на них.

вы обычно сталкиваетесь с #2, когда Мокко не получает ошибки утверждения от обратного вызова. Это вызвано тем, что какой-то другой код проглатывает исключение дальше по стеку. правильный способ справиться с этим-исправить код и не проглотить ошибку.

когда внешний код проглатывает свои ошибки

в случае, если это библиотечная функция, которую вы не можете изменить, вам нужно поймать ошибку утверждения и передать ее на Mocha самостоятельно. Вы делаете это, обертывая свой обратный вызов утверждения в блоке try / catch и передавая любые исключения сделано обработчик.

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

этот шаблон можно, конечно, извлечь в какую-то полезную функцию, чтобы сделать тест немного более приятным для глаз:

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

ускорение сетевых тестов

кроме того, я предлагаю вам взять совет о начале использования тестовых заглушек для сетевых вызовов, чтобы сделать тесты пройти без необходимости полагаться на функционирующую сеть. Используя Мокко, чай и Синон тесты могут выглядеть примерно так это

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

});

посмотреть Синон это nise docs для получения дополнительной информации.

для меня проблема была на самом деле описать функцию, который, когда предоставляется функция стрелки, заставляет мокко пропустить тайм-аут, и ведут себя не последовательно. (С помощью ES6)

так как ни одно обещание не было отклонено, я все время получал эту ошибку для разных тестов, которые терпели неудачу внутри блока описания

Так вот как это выглядит, когда не работает должным образом:

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

и это работает с помощью анонимной функции

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

Надежда он помогает кому-то, моя конфигурация выше: (nodejs: 8.4.0, npm: 5.3.0, mocha: 3.3.0)

немного поздно, но кто-то может использовать это в будущем...Вы можете увеличить время ожидания теста, обновив сценарии в своем пакете.json со следующим:

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

запустить тесты с помощью команды test