如何处理猫鼬测试中的 Schema.save 延迟 [英] How to deal with Schema.save delay in mongoose tests

查看:45
本文介绍了如何处理猫鼬测试中的 Schema.save 延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个猫鼬模式方法,它插入一条新记录然后返回一个激活码.在我的测试中,我想调用这个方法然后运行一个查询来验证它添加的记录的一些事情.问题是该方法在记录对后续查询可见之前返回,即使我在返回之前等待 .save .

I have a mongoose schema method that inserts a new record then returns an activation code. In my tests I want to call this method then run a query that verifies some things about the record it has added. The problem is the method returns before the record has become visible to the subsequent query, even though I am awaiting the .save before returning.

我已经通过在方法调用和后续查询之间添加延迟来验证这一点.没有延迟,第二个查询返回空值.延迟超过约 30 毫秒,查询返回我期望的结果并且测试通过.

I have verified this by adding a delay between the method call and the subsequent query. Without the delay the second query returns null. With a delay of above ~30ms the query returns what I was expecting and the test passes.

我认为这么短的延迟不会在生产中造成任何问题,但是我如何在测试中解决它而不诉诸丑陋和任意的 setTimouts?有没有办法在我的测试中调用 .save 运行并同步返回?或者是否有我可以侦听的事件,在写入数据时会触发该事件.还是我想的全错了?

I don't think such a short delay will cause any problems in production but how can I account for it in my tests without resorting to ugly and arbitrary setTimouts? Is there a way to make the call to .save run and return synchronously in my tests? Or is there an event I can listen for which fires when the data has been written. Or am I thinking about this all wrong?

// My method
userSchema.statics.addNewUser = async function (params) {
    const randomSlug = cryptoRandomString({ length: 64, type: "url-safe" })
    const hashedPassword = await bcrypt
        .genSalt(10)
        .then(salt => bcrypt.hash(params.password, salt))
    const user = new User({
        name: params.name,
        email: params.email,
        password: hashedPassword,
        active: false,
        activationCode: randomSlug
    })
    await user.save((err) => { if (err) throw(err)})
    return randomSlug
}


// My test
it("Should create a new account and return an activation code", async () => {
    const activationCode = await User.addNewUser({
        name: "Bob",
        email: "Bob@iscool.com",
        password: "password",
    })
    assert.match(activationCode, /^.{64}$/)

    // Result is null unless there is a delay of ~30ms here
    const query = User.findOne({ activationCode })
    query.select("name email active password")
    const result = await query.exec()
    console.log("RESULT IS:", result)
    assert(result)

})

推荐答案

Mongoose 支持双重承诺和回调 API.

Mongoose supports a dual promise and callback API.

Model.prototype.save() 提供回调函数 返回 undefined 而不是 Promise,所以 await 立即返回.

Supplying a callback function to Model.prototype.save() returns undefined instead of a Promise, so the await returns immediately.

await user.save()

被拒绝的承诺将被 async 函数自动抛出.

Rejected promises will be thrown automatically by the async functions.

这篇关于如何处理猫鼬测试中的 Schema.save 延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆