В тестировании mocha при вызове асинхронной функции как избежать ошибки тайм-аута: превышен тайм-аут 2000ms
в моем приложении узла я использую mocha для тестирования моего кода. При вызове многих асинхронных функций с помощью 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 для получения дополнительной информации.
для меня проблема была на самом деле описать функцию, который при условии функции стрелки, заставляет mocha пропустить тайм-аут, и ведут себя не последовательно. (Используя 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