问题
I am creating some mocha tests for my Node app. In my test, before retrieving some docs that are created, I need to first create those docs in the database. Then I retrieve them and run some tests on the results.
The problem I'm noticing is that even though I've included the function that needs to run to create the docs in the first before()
block, and even though I'm awaiting the result of the doc creation function, my tests run BEFORE the docs are finished being created. It seems the before()
block doesn't do quite what I think it does.
How can I rectify this to ensure the doc creation has finished BEFORE the test checks run?
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
});
回答1:
You are mixing promises and async together which is not needed. The Nodejs driver supports async/await so rather keep it consistent.
I cannot see the seedJobs
function but assume it works as expected. I suggest you update the before
function as per the example below.
You also have an error initializing the date, the format should be:
const testDate = new Date(2019, 1, 1);
See the below init of mongodb client and use of 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");
});
});
});
来源:https://stackoverflow.com/questions/58921528/mocha-tests-running-before-docs-defined-in-before-block-are-done