首页 文章

处理承诺拒绝与柴

提问于
浏览
0

我有以下验证函数检查用户是否存在:

validate.user = async (user, password) => {
    const matches = await bcrypt.compare(password, user.password);
    if (matches) return user;
    if (!matches) {
        return validate.logAndThrow('User password does not match');
    }
    return validate.logAndThrow('Error in bcrypt compare');
};

使用Chai的以下测试应该测试这个:

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

    describe('#user', () => {
        it('show throw if user is undefined', () => {
            expect(() => validate.user(undefined, 'pass')).to.throw('User does not exist');
        });

错误确实会被抛出,但是mocha在控制台中显示以下内容:

2)如果用户未定义则显示throw(节点:18587)UnhandledPromiseRejectionWarning:未处理的promise拒绝(拒绝id:2):错误:用户不存在

所以我的问题是,我如何重写测试,以便它能够捕获承诺拒绝?

2 回答

  • 1

    要测试基于承诺的函数(异步),请使用chai-as-promised插件:

    expect(validate.user(undefined, 'pass')).to.be.rejectedWith(Error, 'User does not exist');
    

    在这种情况下,您不会将 () => validate.user() 放入 expect ,因为它不会返回承诺 . async functions always return a promise ,所以只需在 expect 内调用您的方法(不将其包装到方法中)就足够了 .

    我希望这很清楚:)如果您有任何疑问 - 请随时提出 .

  • 1

    我不完全确定是摩卡会抛出那种未经处理的拒绝 .

    我认为这是你的bcrypt.compare本质上是异步并使用回调 . await 无法真正使用异步功能开箱即用 .

    但你可以像这样使用节点 util 库来宣传异步调用:

    const util = require('util');
    const bcrypt = require('bcrypt');
    
    const bcryptCompare = util.promisify(bcrypt.compare);
    

    现在你可以像你想的那样使用 await bcryptCompare(password, user.password); . 请注意,我在等待电话后改变了常数 .

    另外要使用 async/await 来处理拒绝,你应该像这样使用 try/catch

    let matches;
    try {
        matches = await bcryptCompare(password, user.password);
    } catch(bcryptError) {
        throw new Error(bcryptError);
    }
    

相关问题