mardi 9 octobre 2018

Testing validation in Mongoose without hitting the database

If I have in my application the following model:

// employee.js

const mongoose = require('mongoose');

const validators = require('./validators');

const EmployeeSchema = new mongoose.Schema({
  firstName: { type: String, required: true },
  lastName: { type: String, required: true },
  referredBy: {
    type: Schema.Types.ObjectId,
    ref: 'Employee',
    validate: {
      isAsync: true,
      validator: validators.referralValidator
    }
  }
});

module.exports = mongoose.model('Employee', EmployeeSchema);

Basically, it's a model for an employee in a firm. That employee could have been referred to work at the firm by a different, existing, employee, so there is a self-referencing in the Employees collection.

The validation makes sure that the user doesn't enter an id of an employee who doesn't exist in the database already. It looks like this:

// validators.js

const mongoose = require('mongoose');

function referralValidator(val, callback) {
  if (val) {
    const Employee = mongoose.model('Employee');
    Employee.findById(val.toString(), (err, found) => {
      callback(found !== null);
    });
  } else {
    callback(true);
  }
}

module.exports = {
  referralValidator
};

Now, I would like to test that this validation work (could be one of many other validations that I'll write in the future for other fields that will be added to the model). However, I would like not to hit the database in the test, so I want to stab out the findById to control manually what the value of "found" will be for the test. I couldn't figure out how to go around the mongo driver that mongoose employs behind the scenes.

How could I stab this function? Or, alternatively, is there a better way to implement the validator in order to make it more testable?

Aucun commentaire:

Enregistrer un commentaire