How to deal with Schema.save delay in mongoose tests

我与影子孤独终老i 提交于 2020-12-12 12:18:52

问题


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.

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.

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)

})


回答1:


Mongoose supports a dual promise and callback API.

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

await user.save()

Rejected promises will be thrown automatically by the async functions.



来源:https://stackoverflow.com/questions/63124330/how-to-deal-with-schema-save-delay-in-mongoose-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!