简体   繁体   English

单元测试:使用填充时如何模拟猫鼬代码?

[英]Unit test: How to mock mongoose code when using populate?

I have a mongoose model with a static function that finds an employee document by ID and populates referenced manager and interviewer fields. 我有一个带有静态函数的猫鼬模型,该函数通过ID查找员工文档并填充引用的managerinterviewer字段。

employeeSchema.statics.findAndPopulateById = function(id) {
  return this.findById(id)
    .populate("manager", "firstname lastname email")
    .populate("interviewer", "email")
    .then(employee => {
      if (!employee) {
        throw new errors.NotFoundError();
      }
      return employee;
    });
}

I understand how to test this function when it doesn't contain the populate chain, but the populate part is throwing me for a loop. 我了解如何在不包含填充链的情况下测试此函数,但是填充部分使我陷入循环。

Specifically, I am trying to test that the NotFoundError exception is thrown when no matching record is found, but I am confused how to mock the findById method so that .populate() can be called on the return value. 具体来说,我正在尝试测试未找到匹配记录时是否引发NotFoundError异常,但是我困惑如何模拟findById方法,以便可以在返回值上调用.populate()

If I were testing this method without the .populate() chain, I would do something like 如果我在没有.populate()链的情况下测试此方法,我会做类似的事情

let findByIdMock = sandbox.stub(Employee, 'findById');
findByIdMock.resolves(null);

return expect(Employee.findAndPopulateById('123')).to.be.rejectedWith(errors.NotFoundError);

But this approach, of course, doesn't work when populate is involved. 但是,当涉及到填充时,这种方法当然不起作用。 I think I should be returning a mocked query or something similar, but I also need to be able to call populate again on that mock or resolve it as a promise. 我想我应该返回一个模拟查询或类似的东西,但是我还需要能够再次对该模拟调用populate或将其解析为一个承诺。

How do I write a test for this code? 如何为此代码编写测试? Should my function be structured differently? 我的职能结构应该不同吗?

Alright this ended up being easier than I anticipated, I just needed to add a call to .exec() between my final .populate() and .then() to make the test below work. 好吧,这结束了比我预期的更简单,我只需要添加一个调用.exec()我最后间.populate().then()使下面工作的考验。

it("should throw not found exception if employee doesn't exist", () => {
  const mockQuery = {
    exec: sinon.stub().resolves(null)
  }
  mockQuery.populate = sinon.stub().returns(mockQuery);

  let findById = sandbox.stub(Employee, 'findById');
  findById.withArgs(mockId).returns(mockQuery);

  return expect(Employee.findAndPopulateById(mockId)).to.be.rejectedWith(errors.NotFoundError);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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