Mocha,如何在没有UnhandledPromiseRejectionWarning的情况下测试异步代码

时间:2018-01-30 01:23:02

标签: node.js asynchronous testing mocha

我正在用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();
    });
});

但测试不会失败,因为它会抛出请求处理回调。

所以我用Google搜索并发现我的问题可以使用promises来解决,现在测试失败了。这是结果代码:

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?

1 个答案:

答案 0 :(得分: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);
});