确保在 Mocha 测试中不使用 setTimeout() 检索文档
Ensuring Document is Retrieved Without Using setTimeout() in Mocha Test
我已经使用 Mocha 和 Chai 在我的 Node 项目中编写了一些测试。在我的一个测试中,我创建了一个 agenda.js 作业,然后将其保存到数据库中。然后我从我的 MongoDB 数据库中检索该文档并 运行 对其进行一些检查。经过多次配置后,我找到了一个适用于测试的结构。但是为了让它工作,我必须在第一个 it
块中添加一个 setTimeout()
,否则 it
检查会在从数据库中检索文档之前开始 运行ning .
在进行以下构建时,我想知道执行此操作的更好方法是什么。在我看来,Mocha 中 before
块的全部意义在于确保其中定义的任何工作都已完成 BEFORE it
检查 运行.在我的情况下似乎没有发生这种情况 - 因此需要 setTimeout()
。那么,如果不使用 `setTimeout(),我该如何实现呢?:
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);
});
});
});
before 中的异步函数可能会提前解决。在那种情况下,我会将它包装在一个新的 Promise 中,并在我确定所有异步代码都已解析完成时解析。
//...
before(function () {
return new Promise((resolve, reject) => {
client.connect(async function (err) {
if(err) return reject(err);
try {
const db = await client.db(dbName);
result = await db.collection("jobs").findOne({
"name": jobName
});
client.close();
} catch(err){
return reject(err);
}
return resolve();
});
});
})
//...
或者,调用 done
回调,如果出现错误则传入一个真值。
//...
before(function (done) {
client.connect(async function (err) {
if(err) return done(err);
try {
const db = await client.db(dbName);
result = await db.collection("jobs").findOne({
"name": jobName
});
client.close();
} catch(err){
return done(err);
}
done();
});
})
//...
我已经使用 Mocha 和 Chai 在我的 Node 项目中编写了一些测试。在我的一个测试中,我创建了一个 agenda.js 作业,然后将其保存到数据库中。然后我从我的 MongoDB 数据库中检索该文档并 运行 对其进行一些检查。经过多次配置后,我找到了一个适用于测试的结构。但是为了让它工作,我必须在第一个 it
块中添加一个 setTimeout()
,否则 it
检查会在从数据库中检索文档之前开始 运行ning .
在进行以下构建时,我想知道执行此操作的更好方法是什么。在我看来,Mocha 中 before
块的全部意义在于确保其中定义的任何工作都已完成 BEFORE it
检查 运行.在我的情况下似乎没有发生这种情况 - 因此需要 setTimeout()
。那么,如果不使用 `setTimeout(),我该如何实现呢?:
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);
});
});
});
before 中的异步函数可能会提前解决。在那种情况下,我会将它包装在一个新的 Promise 中,并在我确定所有异步代码都已解析完成时解析。
//...
before(function () {
return new Promise((resolve, reject) => {
client.connect(async function (err) {
if(err) return reject(err);
try {
const db = await client.db(dbName);
result = await db.collection("jobs").findOne({
"name": jobName
});
client.close();
} catch(err){
return reject(err);
}
return resolve();
});
});
})
//...
或者,调用 done
回调,如果出现错误则传入一个真值。
//...
before(function (done) {
client.connect(async function (err) {
if(err) return done(err);
try {
const db = await client.db(dbName);
result = await db.collection("jobs").findOne({
"name": jobName
});
client.close();
} catch(err){
return done(err);
}
done();
});
})
//...