2
votes

I'm writing some tests for a mongoose model, and it contains a field which references another model. I run a before() and create an object, and then I run my tests. Inside the created callback I see that the object has an ID in the proper field. Inside the 1st "it" statement I also see the ID and my test passes. In every following "it" statement it disappears and is null. I found that if I actually create the referenced object beforehand then the field remains. I did not think that mongoose/mongo actually checks all ObjectId references, but if it does, does anyone know how/why it works? If not, what exactly may be causing this phenomenon?

The field that disappears is the 'host' field in the OfficeHoursSchema. Btw, this still doesn't work even if the required is set to false.

Model Definition:

var appointmentSchema = new Schema({
  attendee: { type: Schema.Types.ObjectId, ref: "Student", required: false },
  startTime: { type: Date },
  duration: Number
});

var statusStates = ['open','closed']

var OfficeHoursSchema = new Schema({
  host: { type: Schema.Types.ObjectId, ref: "Employee" , required: true},
  appointments: [appointmentSchema],
  description: String,
  location: String,
  startDateTime: { type: Date, default: Date.now },
  endDateTime: { type: Date, default: Date.now },
  status: { type: String, default: 'open' , enum: statusStates},
  seqBooking: {type: Boolean, default: true}
});

Tests:

describe('OfficeHours Model', function(){
    var hostId = new mongoose.Types.ObjectId;
    var mins = 15;
    var numAppointments = ohDurationInMs/appointmentDuration;
    var officeHour;
    var officeHourToCreate = {
        host: hostId,
        appointments: appointmentsToCreate(),
        description: 'meeting',
        location: 'room 1',
        startDateTime: new Date(startTime), //3/6/2015 at 3:30pm EST
        endDateTime: new Date(endTime), //2 hours later. 3/6/2015 at 5:30pm EST
        totalDuration: ohDurationInMs/(60*1000)
    };

    before(function(done){
        OfficeHour.create(officeHourToCreate,function(err,createdOH){
            officeHour = createdOH;;
            done();
        });
    });

    it('1st It statement',function(){
        expect(officeHour.host).to.be.ok;
    });

    it('2nd It statement',function(){
        expect(officeHour.host).to.be.ok;
    });

});

The 1st it statement passes, but for the second the .host field is Null.

Here is basically what works

Working:

before(function(done){
    var employee = new Employee({password: 'asdfasdfsafasdf'});
    employee.save(function(err,createdEmployee){
        officeHourToCreate.host = createdEmployee._id;
        OfficeHour.create(officeHourToCreate,function(err,createdOH){
            officeHour = createdOH;;
            done();
        });
    })
});

I feel like some kind of check that the ObjectId exists elsewhere must be happening but can anyone point me to some documentation of this behavior? Thanks so much for reading this.

1
What are you expecting this to do var hostId = new mongoose.Types.ObjectId; ?Tom Hallam
I expect it go give me a randomly generated ID with the type being the specific ObjectId type in mongoose.Justin Sung

1 Answers

0
votes

I think it's because the second time before() is called, the fact you refering to the instantiated ObjectId, which the second time round is not creating a new one as you'd expect.

Can you try this:

before(function(done){
    OfficeHour.create({
    host: new mongoose.Types.ObjectId, 
    // btw I've never seen that syntax for making a new random ID, but if it does what you want it to do then go ahead!
    appointments: appointmentsToCreate(),
    description: 'meeting',
    location: 'room 1',
    startDateTime: new Date(startTime), //3/6/2015 at 3:30pm EST
    endDateTime: new Date(endTime), //2 hours later. 3/6/2015 at 5:30pm EST
    totalDuration: ohDurationInMs/(60*1000)
}, function(err,createdOH){
        officeHour = createdOH;;
        done();
    });
});