Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize Model Unit Test

I have a User sequelize model that has a beforeCreate hook that encrypts the password using bcrypyt. Bcrypyt is loaded as a dependency by the model using a require statement.

Now, I'm writing my tests for my models and I want to write a test that ensures bcrypt is hashing the password on create.

At the moment, I have added a setter onto the User model that sets the bcrypt object. In my tests, I can then create a spy using sinon and inject the spy using the setter and ensure it is called on create.

Is this the correct way to do it? I feel as if I'm creating a setter purely for my tests and that it serves no other purpose.

like image 940
sb89 Avatar asked Apr 17 '15 11:04

sb89


1 Answers

How to test is a point of religious debate in the development community. I'm of the opinion that as long as you are testing, exactly how that gets done is a matter of preference. I tend to write tests that behave like my application as much as possible.

If you want to ensure that bcrypt is properly hashing the user password on create, then create a user, save it, and check the password.

This can be more work with making sure a test DB is running for the tests, but I find it provides good results. And the setup and teardown is very scriptable.

For this example, you don't even need a test framework to test this behaviour.

var User = require( './User' )
var BCRYPT_HASH_BEGINNING = '$2a$'
var TEST_PASSWORD = 'hello there'

User.create({ password: TEST_PASSWORD }).then( function( user ){
  if( !user ) throw new Error( 'User is null' )
  if( !user.password ) throw new Error( 'Password was not saved' )
  if( user.password === TEST_PASSWORD )
    throw new Error( 'Password is plaintext' )
  if( user.password.indexOf( BCRYPT_HASH_BEGINNING ) === -1 )
    throw new Error( 'Password was not encrypted' )
})
like image 166
JoshWillik Avatar answered Sep 18 '22 15:09

JoshWillik