【问题标题】:How to enforce before() to complete before executing tests in Mocha?如何在 Mocha 中执行测试之前强制 before() 完成?
【发布时间】:2017-06-10 04:40:04
【问题描述】:

我是 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 ...
    });
});

我面临的问题是,Mocha 甚至在 dbCleanup() 函数完成之前就开始运行我的测试。这会导致我的数据库崩溃,并且我遇到了不受欢迎的行为。

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

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

谢谢!

【问题讨论】:

    标签: javascript mocha.js chai


    【解决方案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

    【讨论】:

    • 感谢您的回复。我尝试了这两个选项,但遇到了同样的问题。我的测试甚至在 dbCleanup() 函数完成之前就开始运行。我现在想知道我的清理功能和我使用 Promises 的方式是否真的在发挥作用:-(
    • try/catch 也有错误,对于 Promise,您需要使用 Promise.catch。我改变了它并添加了一个工作示例。
    • 非常感谢@luisenrike 详细说明了解决方案。这对我有用。
    猜你喜欢
    • 2016-08-07
    • 2019-10-14
    • 1970-01-01
    • 2017-02-05
    • 2019-08-21
    • 2020-03-14
    • 1970-01-01
    • 2021-11-15
    • 2020-11-02
    相关资源
    最近更新 更多