如何在Mocha中执行测试之前强制执行before()?

时间:2017-06-10 04:40:05

标签: javascript mocha chai

我是JavaScript生态系统的新手。我正在尝试使用Mocha / Chai为我的REST API编写几个API测试。我的要求是我必须在运行每个测试用例之前清理我的数据库。所以,我在名为 dbCleanup.js

的文件中编写了以下代码
var config = require("config.json");
const pg = require('pg');

var connectionString = config.pgConnectionString
console.log("DB Connection String: ", connectionString)

function dbCleanup() {

    var dbTables = ["projects", "employees"];

    var pgClient = new pg.Client(connectionString);

    var promise = new Promise(function (resolve, reject) {
        pg.connect(connectionString, (err, pgClient, done) => {
            if (err) {
                done();
                console.log(err);
                reject();
            }

            for (i = 0; i < dbTables.length; i++) {
                query = "TRUNCATE " + dbTables[i] + " CASCADE;"
                pgClient.query(query, function (err, res) {
                    if (err) {
                        done();
                        console.error('error running query', err);
                        reject();
                    }
                    resolve();
                });
            }
        });
    });

    pgClient.end()

    return promise;
}

exports.dbCleanup = dbCleanup;

我有另一个名为 globalBefore.js 的文件,其中我有以下代码:

var dbCleanup = require('./dbCleanup.js').dbCleanup;

function _beforeClean(done) {
    try {
        dbCleanup()
            .then(done)
    } catch (err) {
        console.error(err);
    }
}

exports.beforeCleanup = _beforeClean;

现在在我的Mocha test.js 文件中,我尝试按如下方式调用数据库清理函数:

var request = require("request");
var rp = require("request-promise");
var config = require("../config.json");
var expect = require('chai').expect;
var data = require("./data.json");

var globalBefore = require("../globalBefore.js");


describe("POST /employees/", function () {

    console.log("clearing db tables...")
    before(globalBefore.beforeCleanup, function (done) {
        done();
    });

    beforeEach(function (done) {
    ... do some business logic related work here ...
    });


    it.only('Try create an employee', function (done) {
    ... API call to create an employee and use Chai assertions to validate ...
    });
});

我面临的问题是,即使在dbCleanup()函数完成之前,Mocha也会继续运行我的测试。这导致我的数据库崩溃,我遇到了不受欢迎的行为。

来自SO社区的任何人都可以帮忙吗?我尝试了在网络上找到的各种选项,但无法解决问题。如代码片段所示,我希望使用Promise应该已经解决了问题

为了更通用,如何在Mocha运行测试的 it 子句之前强制执行之前子句中的指令?

谢谢!

1 个答案:

答案 0 :(得分:1)

您正在以错误的方式使用before。试试这个:

before(function (done) {
    globalBefore.beforeCleanup(done);
});

before(globalBefore.beforeCleanup);

globalBefore.js

var dbCleanup = require('./dbCleanup.js').dbCleanup;

function _beforeClean(done) {
    dbCleanup().then(done).catch(done);
}

exports.beforeCleanup = _beforeClean;

示例(我只更改了dbCleanup.js以使用另一个承诺)

dbCleanup.js

function dbCleanup() {

    return new Promise(function (resolve, reject) {
        setTimeout(resolve, 2000);
    });

}

exports.dbCleanup = dbCleanup;

globalBefore.js

var dbCleanup = require('./dbCleanup.js').dbCleanup;

function _beforeClean(done) {
    dbCleanup().then(done).catch(done);
}

exports.beforeCleanup = _beforeClean;

index.js

var globalBefore = require("../globalBefore.js");

describe("POST /employees/", function () {

    this.timeout(5000); // because the promise take 2000ms

    console.log("clearing db tables...")
    before(function (done) {
        console.log('before calling beforeCleanup');
        globalBefore.beforeCleanup(function () {
            console.log('after calling beforeCleanup');
            done(); // done cleaning db
        });
    });

    /* Without the console.logs
    console.log("clearing db tables...");
    before(globalBefore.beforeCleanup)
    */

    beforeEach(function (done) {
        // ... do some business logic related work here ...
        console.log('beforeEach');
        done();
    });


    it.only('Try create an employee', function (done) {
        // ... API call to create an employee and use Chai assertions to validate ...
        console.log('it');
        done();
    });
});

<强>输出

clearing db tables...

  POST /employees/
before calling beforeCleanup
after calling beforeCleanup
beforeEach
it
    √ Try create an employee


  1 passing (2s)

https://mochajs.org/#hooks