Я создаю несколько тестов с использованием Mocha / Chai в моем проекте Node. В одном конкретном тесте мне нужно сначала сохранить 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()
, но это тоже не сработало (тот же результат - документ находится только при ВТОРОМ запуске тестового файла):
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);
});
});
});
1 ответ
Он не выполняется it
до завершения before
, но он запускается перед всем:
client.connect(async function (err) {
...
});
Мокко, при создании набора тестов запускается такой код:
вызывать каждую функцию, которая передается в
describe
- собрать все крючки
it
иbefore/after*
- именно тогда и вызывается ваш фрагмент
client.connect
!
- собрать все крючки
затем, после создания всего дерева наборов / тестов, для каждого набора
- назвать подходящим перед * крючками
- вызвать все
it
s - тесты, возможно, окруженныеbefore/afterAll
хуками - вызов
after
ловушек
Каждый запуск ловушки / теста ждет завершения, по крайней мере, в вашем случае, поскольку вы правильно используете async / await
Также обратите внимание, что это очень подозрительно:
await setTimeout(() => {
console.log('finished pausing for 5 seconds...');
}, 5000);
Это ничего не дожидается, потому что setTimeout
возвращает таймер (возможно, номер), и не совсем точно определено, что await
должен делать с этими данными, поскольку это не обещает. Конечно, не дожидается 5 секунд.
Правильное обещанное ожидание выглядит следующим образом:
await new Promise(resolve => setTimeout(resolve, 5000))
Похожие вопросы
Новые вопросы
node.js
Node.js - это неблокирующая асинхронная среда ввода-вывода, основанная на событиях, использующая движок Google V8 JavaScript и библиотеку libuv. Он используется для разработки приложений, которые интенсивно используют возможность запуска JavaScript как на клиенте, так и на стороне сервера, и, следовательно, выигрывают от повторного использования кода и отсутствия переключения контекста.