在 Mocha 的测试 运行 之前块中定义的函数未完成
Function Defined in Before Block Not Finishing Before Tests Run in Mocha
我正在我的 Node 项目中使用 Mocha/Chai 创建一些测试。在一个特定的测试中,我需要先将 document
保存到数据库中,然后再检索它并 运行 对找到的文档进行一些检查。
我 运行 遇到的问题是 it
检查在文档完成保存到数据库之前 运行 进行。我不明白为什么会这样,因为我正在 before()
块中进行保存——根据 Mocha 文档,在同一描述块中的测试之前应该 运行 ,见下文来自文档:
> With its default "BDD"-style interface, Mocha provides the hooks
> before(), after(), beforeEach(), and afterEach(). These should be used
> to set up preconditions and clean up after your tests.
>
> describe('hooks', function() { before(function() {
> // runs before all tests in this block });
>
> after(function() {
> // runs after all tests in this block });
>
> beforeEach(function() {
> // runs before each test in this block });
>
> afterEach(function() {
> // runs after each test in this block });
>
> // test cases });
澄清一下,当我 运行 第二次(以及所有后续时间)测试时,所有检查都通过了,因为到那时它可以在数据库中找到文档。
我在这里错过了什么?
这是我的代码:
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(2000);
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); // Here is where I save the job to the DB
});
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'", function () {
expect(result).to.have.property("name");
});
it("should have a 'name' of 'Contact FirstName To Proper Case'", 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);
});
});
我还尝试将 it
检查放在后续的 describe()
块中,但这也没有用(同样的结果——文档仅在 SECOND 运行 上找到测试文件):
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(2000);
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); // Here is where I save the job to the DB
});
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();
});
describe("Check Contact FirstName To ProperCase Found Job", function () {
it("should have a property 'name'", function () {
expect(result).to.have.property("name");
});
it("should have a 'name' of 'Contact FirstName To Proper Case'", 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);
});
});
});
it
运行ning 之前 before
完成,但这是 运行 一切之前:
client.connect(async function (err) {
...
});
Mocha,当创建测试 suide 时 运行s 代码如下:
调用传递给 describe
的每个函数
- 收集所有
it
和 before/after*
钩子
- 那是您的
client.connect
片段实际被调用的时间!
然后,在创建整个 suite/test 树之后,对于每个套件
- 在* hooks 之前调用适当的方法
- 调用所有
it
s - 测试,可能被 before/afterAll
钩子包围
- 调用
after
钩子
每个挂钩/测试 运行 至少在您的情况下等待完成,因为您正确使用 async/await
此外,请注意,这很可疑:
await setTimeout(() => {
console.log('finished pausing for 5 seconds...');
}, 5000);
这不会等待任何事情,因为 setTimeout
returns 对其进行计时(可能是数字)并且没有很好地定义 await
应该如何处理这些数据,因为这不是承诺。
当然,它不会等待 5 秒。
正确的承诺等待如下所示:
await new Promise(resolve => setTimeout(resolve, 5000))
我正在我的 Node 项目中使用 Mocha/Chai 创建一些测试。在一个特定的测试中,我需要先将 document
保存到数据库中,然后再检索它并 运行 对找到的文档进行一些检查。
我 运行 遇到的问题是 it
检查在文档完成保存到数据库之前 运行 进行。我不明白为什么会这样,因为我正在 before()
块中进行保存——根据 Mocha 文档,在同一描述块中的测试之前应该 运行 ,见下文来自文档:
> With its default "BDD"-style interface, Mocha provides the hooks
> before(), after(), beforeEach(), and afterEach(). These should be used
> to set up preconditions and clean up after your tests.
>
> describe('hooks', function() { before(function() {
> // runs before all tests in this block });
>
> after(function() {
> // runs after all tests in this block });
>
> beforeEach(function() {
> // runs before each test in this block });
>
> afterEach(function() {
> // runs after each test in this block });
>
> // test cases });
澄清一下,当我 运行 第二次(以及所有后续时间)测试时,所有检查都通过了,因为到那时它可以在数据库中找到文档。
我在这里错过了什么?
这是我的代码:
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(2000);
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); // Here is where I save the job to the DB
});
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'", function () {
expect(result).to.have.property("name");
});
it("should have a 'name' of 'Contact FirstName To Proper Case'", 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);
});
});
我还尝试将 it
检查放在后续的 describe()
块中,但这也没有用(同样的结果——文档仅在 SECOND 运行 上找到测试文件):
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(2000);
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); // Here is where I save the job to the DB
});
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();
});
describe("Check Contact FirstName To ProperCase Found Job", function () {
it("should have a property 'name'", function () {
expect(result).to.have.property("name");
});
it("should have a 'name' of 'Contact FirstName To Proper Case'", 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);
});
});
});
it
运行ning 之前 before
完成,但这是 运行 一切之前:
client.connect(async function (err) {
...
});
Mocha,当创建测试 suide 时 运行s 代码如下:
调用传递给
的每个函数describe
- 收集所有
it
和before/after*
钩子 - 那是您的
client.connect
片段实际被调用的时间!
- 收集所有
然后,在创建整个 suite/test 树之后,对于每个套件
- 在* hooks 之前调用适当的方法
- 调用所有
it
s - 测试,可能被before/afterAll
钩子包围 - 调用
after
钩子
每个挂钩/测试 运行 至少在您的情况下等待完成,因为您正确使用 async/await
此外,请注意,这很可疑:
await setTimeout(() => {
console.log('finished pausing for 5 seconds...');
}, 5000);
这不会等待任何事情,因为 setTimeout
returns 对其进行计时(可能是数字)并且没有很好地定义 await
应该如何处理这些数据,因为这不是承诺。
当然,它不会等待 5 秒。
正确的承诺等待如下所示:
await new Promise(resolve => setTimeout(resolve, 5000))