【问题标题】:Mocha, how to test async code without UnhandledPromiseRejectionWarningMocha,如何在没有 UnhandledPromiseRejectionWarning 的情况下测试异步代码
【发布时间】:2018-07-08 19:30:09
【问题描述】:

我正在使用 mochajs 测试我的服务器端 api 端点,但我不知道如何正确地做到这一点。

我从具有以下逻辑的代码开始:

it('test', (doneFn) => {

    // Add request handler
    express.get('/test', (req, res, next) => {

        // Send response
        res.status(200).end();

        // Run some more tests (which will fail and throw an Error)
        true.should.be.false;

        // And that's the problem, normally my framework would catch the
        // error and return it in the response, but that logic can't work
        // for code executed after the response is sent.
    });

    // Launch request
    requests.get(url('/test'), (err, resp, body) => { // Handle response

        // I need to run some more tests here
        true.should.be.true;

        // Tell mocha test is finished
        doneFn();
    });
});

但是测试并没有失败,因为它抛出了请求处理回调。

所以我四处搜索,发现我的问题可以使用 Promise 解决,而且确实如此,现在测试失败了。这是生成的代码:

it('test', (doneFn) => {

    let handlerPromise;

    // Add request handler
    express.get('/test', (req, res, next) => {

        // Store it in a promise
        handlerPromise = new Promise(fulfill => {

            res.status(200).end();

            true.should.be.false; // Fail

            fulfill();
        });
    });

    // Send request
    requests.get(url('/test'), (err, resp, body) => {

        // Run the other tests
        true.should.be.true;

        handlerPromise
            .then(() => doneFn()) // If no error, pass
            .catch(doneFn); // Else, call doneFn(error);
    });
});

但现在我收到了弃用警告,因为错误是在与引发错误的进程不同的进程中处理的。

错误是:UnhandledPromiseRejectionWarningPromiseRejectionHandledWarning

如何在发送响应后让我的测试失败,并避免出现 unhandledPromiseRejectionWarning?

【问题讨论】:

  • 如果可能,最好使用没有setTimeout 的解决方案。
  • 尝试为进程对象上的unhandledRejection 事件注册一个事件处理程序。 process.on('unhandledRejection', (err, p) => {})。然后在这里显示问题所在。
  • @Cr。 “显示这里有什么问题”是什么意思?事件回调应该怎么做?我无法调用 doneFn() 或重新抛出错误。
  • 记录错误消息并将其附加到您的问题中,因为UnhandledPromiseRejectionWarning 表示promise 中有错误抛出。
  • 是的,错误是由失败的测试引发的。这是一个断言错误,内容类似于:“预期为真为假...”

标签: node.js asynchronous testing mocha.js


【解决方案1】:

这行得通

  it('test', (doneFn) => {

    let bindRequestHandler = new Promise((reslove, reject) => {

        // Add request handler
        app.testRouter.get('/test', (req, res, next) => {

            // Send response
            res.status(200).end();

            try { // Here, we need a try/catch/reject logic because we're in a callback (not in the promise scope)

                // Run some more tests (which will fail and throw an Error)
                true.should.be.false;

            } catch (error) { // Catch the failing test errors and reject them
                reject(error);
            }

            resolve();
        });
    });

    let sendRequest = new Promise((reslove, reject) => {
        // Launch request
        requests.get(url('/test'), (err, resp, body) => { // Handle response

            try {

                // I need to run some more tests here
                true.should.be.true;

            } catch (error) { // Catch the failing test errors and reject them
                reject(error);
            }

            reslove();
        });
    });

    Promise.all([bindRequestHandler, sendRequest])
        .then(res => doneFn())
        .catch(doneFn);
});

【讨论】:

  • 哦,好的。您的代码不是 100% 准确,但我明白这一点。我做了一个版本。
  • 我用工作代码编辑了你的答案。非常感谢
猜你喜欢
  • 2015-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
相关资源
最近更新 更多