简体   繁体   English

Mocha、Chai 和 Sinon 未处理的承诺拒绝警告

[英]Unhandled promise rejection warning with Mocha, Chai and Sinon

I'm using Node and have the following ES6 class:我正在使用Node并且有以下ES6类:

const moment = require('moment');

const sqlFileReader = require('../database/SqlFileReader');
const Lnfe = require('../errors/LoanNotFoundError');

const epoch = '1970-01-01';

/**
 * Take the input params and return the clientId (either found via loanId or untouched) and dateString we need
*/
class ParameterParser {

static async prepareInputParameters(con, req) {

    let clientId = req.query.client_id; // Will be overriden if we need and are able to obtain the client id via loan id.
    let dateString;

    // If no client_id is given but loan_id is, get the client_id via loan_id:
    if (typeof req.query.client_id === 'undefined' && typeof req.query.loan_id !== 'undefined') {
        const { retData } = await sqlFileReader.read('./src/database/sql/getClientIdFromLoanId.sql', [`${req.query.loan_id}`], con, req.logger);
        if (retData.rowsCount > 0) {
            clientId = retData.rows[0].client_id;
        }
        else {
            throw new Lnfe(400, req);
        }
    }

    if (typeof req.query.complaint_init_date === 'undefined') {
        dateString = epoch;
    }
    else {
        // Need to subtract 6 years from the complaint_init_date:
        dateString = moment(moment(req.query.complaint_init_date, 'YYYY-MM-DD').toDate()).subtract(6, 'years').format('YYYY-MM-DD');
    }

    return { clientId, dateString };
}

}

module.exports = ParameterParser;

I am testing it using Mocha , Chai , Chai-as-Promised and Sinon :我正在使用MochaChaiChai-as-PromisedSinon测试它:

'use strict';

const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const sinon = require('sinon');

const parameterParser = require('../../src/core/ParameterParser.js');
const sqlFileReader = require('../../src/database/SqlFileReader.js');
const Lnfe = require('../../src/errors/LoanNotFoundError');

chai.use(chaiAsPromised);
const { expect } = chai;

const retData = {
rowsCount: 1,
rows: [{ client_id: 872 }],
};

const reqDateAndLoan = {
query: {
    complaint_init_date: '2022-03-15',
    loan_id: '1773266',
},
};

const reqDateAndClient = {
query: {
    complaint_init_date: '2022-03-15',
    client_id: '872',
},
};

const reqDateAndLoanIdThatDoesNotExist = {
query: {
    complaint_init_date: '2022-03-15',
    loan_id: '1773266999999999999',
},
};

describe('prepareInputParameters', () => {

sinon.stub(sqlFileReader, 'read').returns({ retData });

it('results in correct client id and date string', async () => {
    const ret = { clientId: 872, dateString: '2016-03-15' };
    expect(await parameterParser.prepareInputParameters(null, reqDateAndLoan)).to.deep.equal(ret);
});

it('results in a client id equal to the that input if the request query contains a client id', async () => {
    const ret = { clientId: '872', dateString: '2016-03-15' };
    expect(await parameterParser.prepareInputParameters(null, reqDateAndClient)).to.deep.equal(ret);
});

it('throws a \'Loan Not Found\' error', async () => {
    expect(parameterParser.prepareInputParameters(null, reqDateAndLoanIdThatDoesNotExist)).eventually.throw(Lnfe, 400, 'Loan Not Found');
});

it('DOES NOT throw a \'Loan Not Found\' error', async () => {
    expect(async () => {
        await parameterParser.prepareInputParameters(null, reqDateAndLoanIdThatDoesNotExist);
    }).to.not.throw(Lnfe, 400, 'Loan Not Found');
});


});

The tests pass but the output has an couple of node warnings:测试通过,但输出有几个节点警告:

prepareInputParameters
✓ results in correct client id and date string
✓ results in a client id equal to the that input if the request query contains a client id
✓ throws a 'Loan Not Found' error
(node:23875) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: Loan Not Found: expected { Object (clientId, dateString) } to be a function
(node:23875) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
✓ DOES NOT throw a 'Loan Not Found' error


4 passing (19ms)

Any ideas how I can get rid of these warnings or what I'm doing wrong?任何想法如何摆脱这些警告或我做错了什么?

Some ideas to help you understand the different stages of the promise that I compiled (the example, ie) with a ES6 class:一些想法可以帮助你理解我用 ES6 类编译的 promise 的不同阶段(例子,即):

// asyncpromiserejection.js // 异步承诺拒绝.js

class asyncpromise{ 
    constructor(s){
        this.s=s
    }
PTest(){    
    var somevar = false;
    somevar=this.s;
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
 //       else
   //         reject();
    });
}
}
module.exports=asyncpromise

With the else part commented, the promise would either resolve if true is passed to the class or the test would timeout because the promise does not know what to do when the value is false.注释掉 else 部分后,如果 true 传递给类,promise 将解决,或者测试将超时,因为当值为 false 时,promise 不知道该怎么做。

// test.js // 测试.js

const asyncpromise=require('./asyncpromiserejection.js')
describe("asyncTests", () => {
it("handles Promise rejection",async ()=>{
    var t=new asyncpromise(false)
    await t.PTest().then(function () {
     console.log("Promise Resolved");
})
})        
});

Fig 1.0图 1.0 图 1.0

Uncomment the else part and you will get the same error but with the warning that promise rejection has been deprecated - Fig 1.1 - because now, although the promise rejection due to the falsey value is handled in the code, the test ie., the calling method, has not handled it.取消对 else 部分的注释,您将得到相同的错误,但警告承诺拒绝已被弃用 - 图 1.1 - 因为现在,尽管在代码中处理了由于 falsey 值导致的承诺拒绝,但测试即调用方法,没处理过。

class asyncpromise{ 
    constructor(s){
        this.s=s
    }
PTest(){    
    var somevar = false;
    somevar=this.s;
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
        else
            reject();
    });
}
}
module.exports=asyncpromise

Fig 1.1图 1.1 图 1.1

Now, handle the promise rejection in the test like so:现在,像这样处理测试中的承诺拒绝:

const asyncpromise=require('./asyncpromiserejection.js')
describe("asyncTests", () => {
it("handles Promise rejection",async ()=>{
    var t=new asyncpromise(false)
    await t.PTest().then(function () {
     console.log("Promise Resolved");
}).catch(()=>{console.log("Promise rejcted")})
})        
});

在此处输入图片说明

And, you can pass some custom message in the reject part of the promise to assert in a test like so:并且,您可以在 promise 的拒绝部分传递一些自定义消息以在测试中断言,如下所示:

const assert=require('chai').assert
const asyncpromise=require('./asyncpromiserejection.js')
describe("asyncTests", () => {
it("handles Promise rejection",async ()=>{
    var t=new asyncpromise(false)
    await t.PTest().then(function () {
     console.log("Promise Resolved");
}).catch((error)=>{
    console.log("Promise rejected")
    assert.equal(error.message,"Promise rejected")
})
})        
});

// asyncpromiserejection.js // 异步承诺拒绝.js

class asyncpromise{ 
    constructor(s){
        this.s=s
    }
PTest(){    
    var somevar = false;
    somevar=this.s;
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
        else
           throw new Error("Promise rejcted")
            //reject();
    });
}
}
module.exports=asyncpromise

在此处输入图片说明

I use to catch unhandled rejection using我用来捕捉未处理的拒绝使用

process.on('unhandledRejection', (err, p) => {
  console.error('unhandledRejection', err.stack, p)
})

so I have the trace and I can locate and fix所以我有跟踪,我可以找到并修复

for DeprecationWarning should work this - I'm not sure, but accordingly with documentation https://nodejs.org/api/process.html#process_event_warning对于DeprecationWarning应该可以工作 - 我不确定,但相应的文档https://nodejs.org/api/process.html#process_event_warning

process.on('warning', (warning) => {
  console.warn(warning.name);
  console.warn(warning.message);
  console.warn(warning.stack);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM