В тестировании 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 ответа:
вы можете либо установить тайм-аут при запуске теста:
mocha --timeout 15000
или вы можете установить тайм-аут для каждого набора или каждого теста программно:
describe('...', function(){ this.timeout(15000); it('...', function(done){ this.timeout(15000); setTimeout(done, 15000); }); });
для получения дополнительной информации см. docs.
Я считаю, что "решение" просто увеличить тайм-ауты скрывает то, что действительно происходит здесь, что либо
- ваш код и / или сетевые вызовы слишком медленные (должно быть менее 100 мс для хорошего пользовательского опыта)
- утверждения (тесты) терпят неудачу, и что-то проглатывает ошибки, прежде чем Мокко сможет действовать на них.
вы обычно сталкиваетесь с #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)