如何将数据传递给mongoose模式构造函数

6

我正在测试我的应用程序,并需要验证mongoose模式构造函数是否使用正确的数据调用。

假设我这样做:

const UserData = new User(user)
console.log(UserData.contructor.args)

我希望看到user对象的日志记录。 可能数据被传递给mongoose模式的构造函数了吗?

请问有人可以告诉我如何访问它吗?

这是我正在尝试解决的具体情况。

export const signup = async (req, res, next) => {
    try {

        //if user object is missing return error
        if (!req.body.user) 
            return next(boom.unauthorized('No user data received.'))        

        //get user data    
        const user                                      = req.body.user,
        { auth: { local: { password, password_2 } } }   = user        

        //check if both passwords match
        if (password !== password_2)
            return next(boom.unauthorized('Passwords do not match.'))

        //check if password is valid
        if (!Password.validate(password)) {          
            const errorData = Password.validate(password, { list: true })
            return next(boom.notAcceptable('Invalid password.', errorData))
        }    

        //creates new mongo user
        const UserData = new User(user)

        //sets user password hash   
        UserData.setPassword(password)

        //saves user to database
        await UserData.save()        

        //returns new users authorization data
        return res.json({ user: UserData.toAuthJSON() })

    } catch(err) {

        //if mongo validation error return callback with error       
        if(err.name === 'ValidationError') {
            return next(boom.unauthorized(err.message))
        }

        // all other server errors           
        return next(boom.badImplementation('Something went wrong', err))
    }

}

And part of test:

describe('Success', () => {
            it('Should create new instance of User with request data', async () => {
                const   req             = { body },
                        res             = {},
                        local           = { password: '1aaaBB', password_2: '1aaaBB'},
                        constructorStub = sandbox.stub(User.prototype, 'constructor')                

                req.body.user.auth.local    = {...local}

                await signup(req, res, next)

                expect(constructorStub.calledOnceWith({...req.body.user})).to.be.true

            })                
        })

编辑:我可以确认它是使用expect(constructorStub.calledOnce).to.be.true调用的。

只是无法验证传递的数据。


你想做什么?通过console.log(UserData)你可以输出整个对象。 - user10251509
我需要在测试套件中使用它,但我无法访问整个对象,所以我正在存根原型。 - iamwtk
1个回答

0

编辑:经过一段时间的交谈,听起来您需要验证是否正确创建了新用户。

我的建议是创建一个新函数createUserFromRequest,它将接受request并返回一个new User

然后,您可以轻松地测试此函数,因为它是纯函数(没有副作用,只有输入和输出)。

此时,您处理程序中的大部分逻辑都在此函数中,因此测试处理程序本身可能不值得,但您仍然可以这样做,例如通过模拟上述函数。

示例:

function createUserFromRequest(request) {
    //get user data    
    const user                                      = req.body.user,
    { auth: { local: { password, password_2 } } }   = user        

    //check if both passwords match
    if (password !== password_2)
        return next(boom.unauthorized('Passwords do not match.'))

    //check if password is valid
    if (!Password.validate(password)) {          
        const errorData = Password.validate(password, { list: true })
        return next(boom.notAcceptable('Invalid password.', errorData))
    }    

    //creates new mongo user
    const UserData = new User(user)

    //sets user password hash   
    UserData.setPassword(password)
    return UserData;
}

请注意:存根和模拟通常是代码异味的表现:可能有更好的测试方式,或者这可能是需要将代码重构为更易于测试的内容的迹象。它们通常指向紧密耦合或混乱的代码。
在这个主题上查看这篇优秀的文章:https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a

要记录参数,您需要执行类似于constructorStub.lastCall.args而不是constructorStub.args的操作--https://sinonjs.org/releases/v7.1.0/spy-call/ - lucascaro
如果这段代码通过了:expect(constructorStub.calledOnceWith({...req.body.user})).to.be.true,那么你就知道构造函数是用这些数据被调用的。如果你想找出为什么测试不通过,你应该让调试器工作并运行你的测试,或者你可以在你的控制器中添加一个临时的 console.log - lucascaro
expect(constructorStub.calledOnceWith({...req.body.user})).to.be.true 失败了,expect(constructorStub.calledOnce).to.be.true 通过了,所以我只需要验证数据。 - iamwtk
通过使用constructorStub.getCalls()constructorStub.getCall(n),您可以获取有关对您的存根的调用的信息。 - lucascaro
好的,大约两个小时后我会启动它,如果有进展我会告诉你。 - iamwtk
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接