【问题标题】:Mocha Tests Running Before Docs Defined in Before Block Are Done在之前块中定义的文档完成之前运行的 Mocha 测试
【发布时间】:2020-03-14 05:36:41
【问题描述】:

我正在为我的 Node 应用程序创建一些 mocha 测试。在我的测试中,在检索一些创建的文档之前,我需要先在数据库中创建这些文档。然后我检索它们并对结果进行一些测试。

我注意到的问题是,即使我在第一个 before() 块中包含了创建文档所需运行的函数,即使我正在等待文档创建函数的结果,我的测试在文档创建完成之前运行。看来before() 块并没有我认为的那样。

如何纠正此问题以确保在测试检查运行之前完成文档创建?

const seedJobs = require('./seeder').seedJobs;

const MongoClient = require('mongodb').MongoClient;
const client = new MongoClient(`${url}${dbName}${auth}`);

describe("Seeding Script", async function () {
  const testDate = new Date(2019, 01, 01);
  let db;
  before(async function () {
    await seedJobs(); // This is the function that creates the docs in the db
    return new Promise((resolve, reject) => {
      client.connect(async function (err) {
        assert.equal(null, err);
        if (err) return reject(err);
        try {
          db = await client.db(dbName);
        } catch (error) {
          return reject(error);
        }
        return resolve(db);
      });
    });
  });
  // Now I retrieve the created doc and run checks on it
  describe("Check VBR Code Update", async function () {
    let result;
    const jobName = 'VBR Code Update';
    this.timeout(2000);
    before(async function () {
      result = await db.collection(collection).findOne({
        name: jobName
      });
    });
    it("should have a property 'name'", async function () {
      expect(result).to.have.property("name");
    });
    it("should have a 'name' of 'VBR Code Update'", async function ()    
      expect(result.name).to.equal(jobName);
    });
    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);
    });
  });
  // Other tests
});

【问题讨论】:

  • 你用的是什么数据库客户端?
  • 上面已经添加了详细信息。

标签: node.js mongodb mocha.js


【解决方案1】:

您将 promise 和 async 混合在一起,这是不必要的。 Nodejs 驱动程序supports async/await 所以宁愿保持一致。

我看不到seedJobs 函数,但假设它按预期工作。我建议您按照下面的示例更新before 函数。

你也有初始化日期的错误,格式应该是:

const testDate = new Date(2019, 1, 1);

看下面mongodb客户端的init和await的使用:

const mongodb = require('mongodb');
const chai = require('chai');
const expect = chai.expect;

const config = {
    db: {
        url: 'mongodb://localhost:27017',
        database: 'showcase'
    }
};

describe("Seeding Script",  function () {
    const testDate = new Date(2019, 1, 1);

    let db;

    seedJobs = async () => {
        const collections = await db.collections();
        if (collections.map(c => c.s.namespace.collection).includes('tests')) {
            await db.collection('tests').drop();
        }

        let bulk = db.collection('tests').initializeUnorderedBulkOp();

        const count = 5000000;
        for (let i = 0; i < count; i++) {
            bulk.insert( { name: `name ${i}`} );
        }

        let result = await bulk.execute();
        expect(result).to.have.property("nInserted").and.to.eq(count);

        result = await db.collection('tests').insertOne({
            name: 'VBR Code Update'
        });

        expect(result).to.have.property("insertedCount").and.to.eq(1);
    };

    before(async function () {
         this.timeout(60000);

        const connection = await mongodb.MongoClient.connect(config.db.url, {useNewUrlParser: true, useUnifiedTopology: true});

        db = connection.db(config.db.database);

        await seedJobs();
    });

    // Now I retrieve the created doc and run checks on it
    describe("Check VBR Code Update", async function () {
        let result;
        const jobName = 'VBR Code Update';
        this.timeout(2000);

        before(async function () {
            result = await db.collection('tests').findOne({
                name: jobName
            });
        });

        it("should have a property 'name'", async function () {
            expect(result).to.have.property("name");
        });
    });
});

【讨论】:

  • 我会尝试这个,但只是为了澄清一下,在您看来,真正的问题是什么?因为,据我所知,问题在于 Mocha 运行事物的顺序。那么你的答案是如何解决这个问题的呢?只是想清楚。谢谢。
  • 你用一个返回的 Promise 包装了 before 并且还使用了 async ,这一切都变得相当混乱。 await client.db(dbName); 不返回承诺等。我会使用承诺并包含 mocha 的 done() 回调来指示之前应该何时结束,或者坚持异步/等待。我个人更喜欢现在坚持使用 asyc/await。看看 done() 回调使用here
  • @Muirik 我知道你发布了另一个关于之前同步性质的问题 - 我在这里更新了答案,包括在我的机器上需要大约 30 秒的 5m 记录的大量批量加载,以演示如何测试将等待before 完成。检查您的加载脚本以确保没有任何内容正在异步运行并在完成之前返回。
  • 最后,当您需要先进行一些设置时,我使用 Mocha 提供的东西让它工作:setTimeout(function() { // do some setup describe('my suite', function() { // ... }); run(); }, 5000);
猜你喜欢
  • 1970-01-01
  • 2016-08-07
  • 2019-11-03
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多