Mocha js太早调用After()

Mocha js Calling After() too Soon?

本文关键字:After 调用 js 太早 Mocha      更新时间:2023-09-26

对Mocha单元测试不熟悉,我有几个运行良好的Mocha示例,但我已经尝试了几个小时来运行这个示例,无论我做什么,after()都比我觉得应该更早被调用。下面是一个例子:

var dummyData = require('./dummyData.js')
describe('mochaTest', function() {
    after(function(done) {
        dummyData.cleanDb(function(){
            done();
        })
    });
    it('should hit the db to get dummy data and send', function(done) {
        dummyData.createDummyData(function(data1, data2, Lookup) {
            Lookup.lookup({
                data1: data1,
                data2: data2
            }, function(err, result) {
                done();
            });
        });
    });
})

然后在dummyData.js中:

exports.createDummyData = function(cb){
   doSomeStuff(function (err, patient) {
     // Connect to db, get some data to pass.
        var Lookup = require(./Lookup.js);
        cb(data1, data2, Lookup);
   })
}
exports.cleanDb = function(cb) {
   // Clear db connections.
   cb();
}

问题是,在测试运行后,after()函数被调用,Lookup函数不能命中db,因为db连接已被清除。为什么在这么早被调用之后,它不应该被调用,直到它语句调用done()对吗?

这是一个老问题,但我遇到过同样的问题,找不到任何解释来解决这个问题。不幸的是,我没有足够的声誉来回答这个问题,所以我将在这里分享我是如何解决这个问题的。

在我的控制器中,我有一个方法概述如下:

exports.insert = (request, response) => {
    UserModel.createUser(request.body)
        .then(() => {
            respond.status(201).send({message: 'User created successfully
        });
};

我意识到这里的问题,是我的测试方法没有等待我的User.insert()的响应,因为这个函数是空的——它不返回值。因此,由于没有理由等待User.insert()的响应,下面的测试将直接跳转到调用done();。这会导致after钩子过早地运行,并在UserModel填充之前关闭与数据库的连接。

// Code is shortened, but my request and response was formed using node-mocks-http package
it('should return status 201', function (done) {
    User.insert(request, response);
    assert(response._getStatusCode() === 201);
    done();
};

我不想说我花了多长时间才意识到这一点。但是,我需要从我的控制器返回一个承诺,这样我的测试函数就会有等待的东西。通过将我的控制器更改为:

exports.insert = async (request, response) => {
    await UserModel.createUser(request.body)
        .then(() => {
            response.status(201).send({message: "User created successfully"});
        })
        .catch(() => {
            response.status(400).send({message: "There is already an account with that email"});
        });
    return response;

我的测试看起来像这样:

it('should return a status code of 201', async function () {
        await User.insert(request, response);
        assert(response._getStatusCode() === 201);
    });

数据库成功填充,我的测试将等待我的promise实现,因此在调用断言之前更新响应。然后after钩子在预期的时候工作。

我希望这能帮助到那些偶然发现这个旧话题的人。