#javascript #node.js #express #async-await #mocha.js
#javascript #node.js #выразить #async-await #mocha.js
Вопрос:
Я пытаюсь протестировать функцию в моем бэкэнде Express / Node, используя Mocha. Я создал заглушку фактического параметра, который модифицируется функцией: у нее есть send
метод, который вызывается в GetValue (функция, которую я хочу протестировать) и ready
параметр, который я инициализирую для нового обещания при создании заглушки и разрешаю при send
вызове заглушки.
Я пытаюсь await
выполнить это обещание, но оно просто зависает (а затем Mocha завершает тест по таймингу). Выводится setTimeout ниже Promise { 'abc' }
, что, я думаю, означает, что обещание выполнено так, как я ожидал, но ожидание никогда не завершается.
Это соответствующий код в тестовом файле:
function ResStubTemplate() {
return {
_json: undefined,
_message: undefined,
json: function(x) {
this._json = x;
return this;
},
send: function(message) {
this._message = message;
this.ready = Promise.resolve("abc");
return this;
},
ready: new Promise(_ => {})
}
}
// This is the test
it("should get the value.", async function(done) {
let req = { query: { groupId: 12345 } };
res = ResStubTemplate();
controller.getValue(req, res);
setTimeout(() => console.log(res.ready), 1000); // prints Promise { 'abc' }
let x = await res.ready; // hangs??
console.log(x); // never prints
done();
}
Это соответствующий код в тестируемом файле:
exports.getValue = function(req, res) {
ValueModel.findOne({groupId: req.query.groupId})
.then(value => res.json({value: value}).send();
};
Ошибка, которую я получаю, это:
Error: Timeout of 5000ms exceeded.
For async tests and hooks, ensure "done()" is called; if returning a Promise,
ensure it resolves. (/.../test/api/controller_test.js)
Комментарии:
1.
new Promise(_ => {})
Это никогда не разрешится.
Ответ №1:
Когда выражение:
let x = await res.ready; // hangs??
… вычисляется, значением является обещание, созданное этим кодом:
ready: new Promise(_ => {})
Это обещание никогда не выполняется, поэтому оно продолжает ждать его.
Позже вы сделаете это:
this.ready = Promise.resolve("abc");
… который заменяет это обещание новым (разрешенным) обещанием, но новое обещание не является ожидаемым значением.