简体   繁体   中英

How to get data passed to mongoose schema constructor

I am testing my application and need to verify that mongoose schema constructor is called with correct data.

let's say I do this:

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

I would expect log of the user object. Probably the data is passed to constructor of mongoose schema?

Can some one please advise me how to access it?

Here is specific case I am trying to solve.

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

            })                
        })

EDIT: I can verify that is is called with expect(constructorStub.calledOnce).to.be.true

Just can't get to verify data passed.

Edit: After talking for some time sounds like what you need is to validate that you are creating a new user correctly.

My suggestion here is to create a new function createUserFromRequest that would take in request and return a new User .

You can then test this function easily as it's pure (no side effects, just input and output).

At this point, most of the logic in your handler is in this function so it would be probably not worth testing the handler itself, but you could still do it, for example by mocking the function above.

Example:

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;
}

Please note : stubs and mocking are usually a code smell: there could either be a better way of testing, or it could be a sign of a need to refactor the code into something more easily testable. They usually point to tightly coupled or cluttered code.

Check out this great article on that topic: https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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