Node.js 确保在Mocha测试中不使用setTimeout()检索文档

Node.js 确保在Mocha测试中不使用setTimeout()检索文档,node.js,mocha.js,chai,Node.js,Mocha.js,Chai,我已经使用Mocha和Chai在我的节点项目中编写了一些测试。在我的一个测试中,我创建了一个agenda.js作业,然后将其保存到数据库中。然后我从MongoDB数据库中检索该文档并对其进行一些检查。经过多次配置之后,我找到了一个测试的结构。但是为了让它工作,我必须在第一个it块中添加一个setTimeout(),因为否则it检查将在从数据库检索文档之前开始运行 虽然下面的建设工程,我想知道什么将是一个更好的方式做这件事。在我看来,摩卡的before模块的全部要点是确保在It检查运行之前完成其中

我已经使用Mocha和Chai在我的节点项目中编写了一些测试。在我的一个测试中,我创建了一个agenda.js作业,然后将其保存到数据库中。然后我从MongoDB数据库中检索该文档并对其进行一些检查。经过多次配置之后,我找到了一个测试的结构。但是为了让它工作,我必须在第一个
it
块中添加一个
setTimeout()
,因为否则
it
检查将在从数据库检索文档之前开始运行

虽然下面的建设工程,我想知道什么将是一个更好的方式做这件事。在我看来,摩卡的
before
模块的全部要点是确保在
It
检查运行之前完成其中定义的任何工作。在我的例子中,这似乎没有发生-因此需要
setTimeout()
。那么,如果不使用`setTimeout(),我如何实现这一点呢


before中的异步函数可能正在早期解析。在这种情况下,当我确信所有异步代码都已解析完成时,我会将其包装在一个新的承诺中并解析

/。。。
前(函数(){
返回新承诺((解决、拒绝)=>{
client.connect(异步函数(err){
如果(错误)返回拒绝(错误);
试一试{
const db=await client.db(dbName);
结果=等待db.collection(“作业”).findOne({
“名称”:工作名称
});
client.close();
}捕捉(错误){
退货拒绝(err);
}
返回resolve();
});
});
})

//…
就个人而言,我会像这样使用'done'回调:
before(function(done){/*一些正在等待异步代码,done(err)*/})我使用的是async/await-因此它应该同样有效。其中一个处理异步代码,并确保在继续之前执行该代码。不过我会试试看,看看是否有什么不同。好吧,你以前有外部的似乎工作得很好,那么内部的有什么不同呢?是
client.connect
在传递给它的异步回调中的等待之前解析吗?我尝试使用done()回调,而不是
before
块中基于承诺的异步/await构造。完全相同的结果。只适用于添加
setTimeout()
块。我不知道。但是无论如何,
it
块为什么要在
块中定义的所有内容完成之前运行?
const assert = require("chai").assert;
const expect = require("chai").expect;
const chai = require("chai");
chai.use(require("chai-datetime"));
const Agenda = require('agenda');

const config = require('./../../configuration');
const url = config.get('MONGO_URL');
const dbName = config.get('MONGO_DATABASE');
const collection = config.get('MONGO_COLLECTION');
const createAgendaJob = require('./../../lib/agenda-jobs/contact-firstname-to-proper-case');

const MongoClient = require('mongodb').MongoClient;
const client = new MongoClient(url);

describe("Contact FirstName to Proper Case", async function () {
  const jobName = "Contact FirstName To Proper Case";
  const testDate = new Date(2019, 01, 01);
  let result;
  let agenda;
  this.timeout(10000);
  before(async function () {
    const connectionOpts = {
      db: {
        address: `${url}/${dbName}`,
        collection
      }
    };

    agenda = new Agenda(connectionOpts);
    await new Promise(resolve => agenda.once('ready', resolve));
    await createAgendaJob(agenda);
  });
  describe("Check Contact FirstName To ProperCase Found Job", async function () {
    let result;
    before(async function () {
      await client.connect(async function (err) {
        assert.equal(null, err);

        const db = await client.db(dbName);

        result = await db.collection("jobs").findOne({
          "name": jobName
        });

        client.close();
      });
    });
    it("should have a property 'name'", async function () {
      await new Promise(resolve => setTimeout(resolve, 1000)); // Here is the setTimout()
      expect(result).to.have.property("name");
    });
    it("should have a 'name' of 'Contact FirstName To Proper Case'", async function () {
      expect(result.name).to.equal("Contact FirstName To Proper Case");
    });
    it("should have a property 'type'", function () {
      expect(result).to.have.property("type");
    });
    it("should have a 'type' of 'normal'", function () {
      expect(result.type).to.equal("normal");
    });
    it("should have a property 'repeatTimezone'", function () {
      expect(result).to.have.property("repeatTimezone");
    });
    it("should have a property 'repeatInterval'", function () {
      expect(result).to.have.property("repeatInterval");
    });
    it("should have a property 'lastModifiedBy'", function () {
      expect(result).to.have.property("lastModifiedBy");
    });
    it("should have a property 'nextRunAt'", function () {
      expect(result).to.have.property("nextRunAt");
    });
    it("should return a date for the 'nextRunAt' property", function () {
      assert.typeOf(result.nextRunAt, "date");
    });
    it("should 'nextRunAt' to be a date after test date", function () {
      expect(result.nextRunAt).to.afterDate(testDate);
    });
  });
});