代码之家  ›  专栏  ›  技术社区  ›  Dan

单元测试:如何在使用populate时模拟mongoose代码?

  •  2
  • Dan  · 技术社区  · 7 年前

    我有一个mongoose模型,它有一个静态函数,可以根据ID查找员工文档并填充引用的文档 manager interviewer 领域。

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

    我知道当这个函数不包含populate链,但populate部分让我陷入循环时,如何测试这个函数。

    NotFoundError 当没有找到匹配的记录时抛出异常,但我不知道如何模拟 findById 方法,以便 .populate() 可以在返回值上调用。

    如果我在没有 .填充() chain,我会这样做

    let findByIdMock = sandbox.stub(Employee, 'findById');
    findByIdMock.resolves(null);
    
    return expect(Employee.findAndPopulateById('123')).to.be.rejectedWith(errors.NotFoundError);
    

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

    如何编写此代码的测试?我的职能应该有不同的结构吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Dan    7 年前

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