Mocha MongoDB Mongoose ObjectId ref 在第一个“it”语句后消失

Posted

技术标签:

【中文标题】Mocha MongoDB Mongoose ObjectId ref 在第一个“it”语句后消失【英文标题】:Mocha MongoDB Mongoose ObjectId ref disappears after first 'it' statement 【发布时间】:2015-05-10 22:37:23 【问题描述】:

我正在为猫鼬模型编写一些测试,它包含一个引用另一个模型的字段。我运行 before() 并创建一个对象,然后运行我的测试。在创建的回调中,我看到该对象在正确的字段中有一个 ID。在第一个“it”语句中,我还看到了 ID 并且我的测试通过了。在随后的每个“it”语句中,它都会消失并且为空。我发现如果我事先实际创建了引用的对象,那么该字段仍然存在。我不认为 mongoose/mongo 实际上会检查所有 ObjectId 引用,但如果确实如此,有谁知道它是如何/为什么工作的?如果不是,究竟是什么原因导致了这种现象?

消失的字段是 OfficeHoursSchema 中的“主机”字段。顺便说一句,即使 required 设置为 false,这仍然不起作用。

模型定义:

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

测试:

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

);

第一个 it 语句通过,但第二个 .host 字段为 Null。

这基本上是有效的

工作:

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();
        );
    )
);

我觉得必须对 ObjectId 是否存在于其他地方进行某种检查,但有人能指出我对这种行为的一些文档吗?非常感谢您阅读本文。

【问题讨论】:

你希望这会做什么var hostId = new mongoose.Types.ObjectId; 我希望它会给我一个随机生成的 ID,其类型是猫鼬中特定的 ObjectId 类型。 【参考方案1】:

我认为这是因为第二次调用 before(),事实上您引用了实例化的 ObjectId,而第二次并没有像您期望的那样创建 new

你可以试试这个:

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();
    );
);

【讨论】:

我所拥有的和你正在尝试的究竟有什么区别?我已经 c/p'd 你的代码来替换我的 before 函数,第二条语句仍然失败。此外,afaik before 意味着它只被调用一次,所有的 'it' 语句都在它之后运行。顺便说一句,我注意到这适用于 beforeEach 而不是 before,特别是因为我只能获取主机字段一次,并且当它每次创建一个新对象时,我可以在每个“it”块中访问它一次。很奇怪。

以上是关于Mocha MongoDB Mongoose ObjectId ref 在第一个“it”语句后消失的主要内容,如果未能解决你的问题,请参考以下文章

在我的 node.js 应用程序中使用 mongodb 和 mongoose 在 Mocha 和 Chai 上运行测试后无法清除数据库

在我的 node.js 应用程序中使用 mongodb 和 mongoose 在 Mocha 和 Chai 上运行测试后无法清除数据库

Mocha 抛出超时,但 Mongoose 将数据保存到 Promise 链中的数据库?

MongoDB / Mongoose 单元测试 - 最佳实践? [关闭]

如何在 mocha 单元测试中使用猫鼬?

Jasmine (mocha) 嵌套“it”测试