Почему зависает вызов await для моего пользовательского обещания?

#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");
  

… который заменяет это обещание новым (разрешенным) обещанием, но новое обещание не является ожидаемым значением.