node.js - 单元测试: How to mock mongoose code when using populate?

标签 node.js mongoose mocha.js sinon chai

我有一个带有静态函数的 Mongoose 模型,该函数通过 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;
    });
}

我知道当这个函数不包含填充链时如何测试它,但是填充部分让我陷入了困境。

具体来说,我正在尝试测试在找不到匹配记录时是否会引发 NotFoundError 异常,但我很困惑如何模拟 findById 方法以便 .populate() 可以在返回值上调用。

如果我在没有 .populate() 链的情况下测试此方法,我会执行类似的操作

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

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

但是,当涉及到 populate 时,这种方法当然不起作用。我认为我应该返回一个模拟查询或类似的东西,但我还需要能够在该模拟上再次调用 populate 或将其解析为 promise 。

如何为这段代码编写测试?我的功能应该采用不同的结构吗?

最佳答案

好吧,这比我预期的要容易,我只需要添加一个对 .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);
});

关于node.js - 单元测试: How to mock mongoose code when using populate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47272519/

相关文章:

javascript - 读入并解析后从 JSON 文件返回一个随机值

javascript - 解决Graphql的异步函数无法返回通过具有rdf数据的Stardog服务器查询的数据

javascript - 如何按照 Mongoose.js 中的 _id 查找项目并处理它?

node.js - 使用 Express 和 Mongoose 时默认启用什么缓存

javascript - 测试未遵守 "beforeEach"内的超时

node.js - LinkedIn API 失败 - Node.js 请求

node.js - 是否可以禁用 Mongoose SchemaTypes 的自动类型转换?

node.js - Mongoose 模式没有选择新属性

javascript - 如何防止文件中的 before 和 beforeEach 应用于所有文件中的所有测试?

node.js - Sails js::测试传递给 View 的变量