Sinon Stub gives unexpected UnhandledPromiseRejectionWarning

632 Views Asked by At

I have a function like so:

    static async performDatabaseConnectivityHealthCheck(logger) {

    let con;
    let ret;

    try {

        con = mysql.createConnection({
            host: config.db.host,
            user: config.db.user,
            password: config.db.password,
            database: config.db.db,
        });

        const { retData } = await sqlFileReader.read('./src/database/sql/healthcheck.sql', [config.db.db], con, logger);

        // Do something with retData.....

    }
    catch (error) {
        logger.error(error.message);
        throw error;
    }
    finally {
        if (con) {
            con.end();
        }
    }
    return ret;

}

And a test like so:

    it('throws a \'Database Healthcheck Error\' error when the Database Healthcheck gives the wrong data', async () => {

//Some irrelevant details here including providing rars for rars.logger in the following...

    sandbox.stub(sqlFileReader, 'read').returns(Promise.reject(new Error("ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'")));

    expect(async () => {
        await RiskAffordabilityReportService.performDatabaseConnectivityHealthCheck(rars.logger);
    }).to.throw('ER_PROCACCESS_DENIED_ERROR: execute command denied to user \'dchambers\'@\'%\' for routine \'uk_txtloan.connection_ids\'');

});

I have two issues. Firstly, the sandbox.stub line gives the following warning, which I am confused about since I ask that the Promise is rejected!

UnhandledPromiseRejectionWarning: Error: ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'

Secondly, the test doesn't pass:

AssertionError: expected [Function] to throw an error.

I'm mainly wondering about the warning. I have tried the following syntax and they give the same error:

sandbox.stub(sqlFileReader, 'read').throws(new Error("ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'"));

sandbox.stub(sqlFileReader, 'read').resolves(Promise.reject(new Error("ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'")));

sandbox.stub(sqlFileReader, 'read').rejects(new Error("ER_PROCACCESS_DENIED_ERROR: execute command denied to user 'dchambers'@'%' for routine 'uk_txtloan.connection_ids'"));

What is the proper way to eliminate the warning? Bonus: Make the test pass.

1

There are 1 best solutions below

0
Estus Flask On BEST ANSWER

Unhandled promise rejection error is thrown in recent Promise implementations if rejected promise wasn't handled, i.e. wasn't chained with catch(...) or then(..., ...).

Chai to.throw assertion wraps a function with try..catch, but no error is thrown in async function. async function is syntactic sugar for a function that returns a promise. Uncaught error inside async function results in returning a rejected promise. Instead, it should be asserted with chai-as-promised assertion:

expect(RiskAffordabilityReportService.performDatabaseConnectivityHealthCheck(rars.logger))
.to.be.rejectedWith(
  Error,
  'ER_PROCACCESS_DENIED_ERROR: execute command denied to user \'dchambers\'@\'%\' for routine \'uk_txtloan.connection_ids\''
);