【问题标题】:Mocha/Chai tests hanging at .should.be.deep.equal despite result existingMocha/Chai 测试挂在 .should.be.deep.equal 尽管结果存在
【发布时间】:2016-03-06 00:54:20
【问题描述】:

我正在使用 Mocha 和 chai 运行一些测试。其中一项测试挂在.should.be.deep.equal 电话上。

这是测试代码:

// Make the fake connection before running tests
before(function(done) {
    mongoose.connect('mongodb://fake.test/TestingDB', function(err) {
        done(err);
    }); 
});

// Test Cases
describe('Testing the functions that deal with users and locations:', function() {
    // Test Setup
    var req = {};
    beforeEach(function(done) {
        mockgoose.reset()
        async.parallel([function(callback){
            sensors.create(testData.deviceData, function(err, model) {
                    if (err) {console.log(err)}
                    callback();
                });
        }, function(callback) {
            locations.create(testData.locationData, function(err, model) {
                    if (err) {console.log(err)}
                    callback();
                });
            }], function(err) {
                done();
            });
    });

    afterEach(function(done) {
        mockgoose.reset();
        done();
    });
    // Tests
    describe('function locationList', function() {
        it('should list the test location', function(done) {
            dbFunctions.locationList(req, function(result) {
                console.log(result) //Prints the whole result
                console.log(testData.locationList)
                result.should.exist; //This doesn't cause it to hang
                result.should.be.deep.equal(testData.locationList) //hangs here
                done(result);
            });
        })
    })
});

这是它正在测试的功能:

exports.locationList = function(req, callback) {
listLocations().then(
    function(data) {
        callback(data);
    },
    function(err) {
        console.log('Error Retrieving Location Information: ' + err);
        callback(err);
    });
};

正如我在 cmets 中所指出的,结果对象存在并被打印到控制台。 results.should.exist; 不会抛出异常,如果我注释掉所有内容,但测试工作正常。出于某种奇怪的原因,尽管 testData.locationListresult 对象都存在,但测试超时。我有 14 个其他测试使用完全相同的语法,没有任何问题。有谁知道是什么原因导致此特定测试发生这种情况?

这是测试的输出:

Testing the functions that deal with users and locations:
    function locationList                            
        [ { devices: {},
            address: '123 Fake St, Waterloo, On',
            location: 'Unittest',
            owner: 'unit@test.com',
            _id: '-1' } ]         
        [ { devices: {},
            address: '123 Fake St, Waterloo, On',
            location: 'Unittest',
            owner: 'unit@test.com',
            _id: '-1' } ]          

            1) should list the test location
0 passing (2s)
1 failing
1) Testing the functions that deal with users and locations: function locationList should list the test location:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
    at null.<anonymous> (C:\Users\My Name\AppData\Roaming\npm\node_modules\mocha\lib\runnable.js:189:19)   

延长超时不起作用。也不会随机放置一些东西(即整数 1.should.be.deep.equal() 函数中。

【问题讨论】:

  • 我认为这不能解决您的问题,但您可能应该只调用 done() 而不是 done(result) 因为传递给 done() 的任何内容都将被解释为错误。

标签: node.js unit-testing mongoose mocha.js chai


【解决方案1】:

猜测:也许问题在于 mongoose 用它自己的函数/成员来装饰 result,当 chai 尝试枚举它们以执行深度比较时,其中一个不知何故陷入了无限循环。

【讨论】:

    【解决方案2】:

    我的猜测是exports.locationList 中的回调被同步调用,并且您的测试用例实际上失败了,抛出了一个异常,该异常永远不会被捕获,因为回调是从一个承诺处理程序中(同步)调用的(更多信息here)。

    试试看是否效果更好:

    dbFunctions.locationList(req, function(result) {
      setImmediate(function() {
        console.log(result) //Prints the whole result
        console.log(testData.locationList)
        result.should.exist; //This doesn't cause it to hang
        result.should.be.deep.equal(testData.locationList) //hangs here
        done(result);
      });
    });
    // or use a module like dezalgo (https://github.com/npm/dezalgo)
    

    根本原因可能是mockgoose

    此外,您没有使用正确的 Node.js 约定,其中回调函数的第一个参数“保留”用于错误。换句话说,您的代码应该类似于:

    if (err) {
      callback(err);
    } else {
      callback(null, data);
    }
    

    您现在将错误 数据作为第一个参数传递。

    【讨论】:

    • 我将您的答案标记为已接受,尽管这并不是我为解决此问题所做的工作。您的建议确实导致出现静默错误,但由于一些奇怪的(与模拟鹅相关的?)原因,它导致我所有其他测试开始以MongoError: topology was destroyed 失败。然后我决定我宁愿不使用承诺,所以编辑我的代码以停止使用它们。这使我所有的测试仍然失败。从差异中,我看到由于某种奇怪的原因返回了整个 mongo 记录,而不仅仅是 _doc。我重写了解包并将它们推入列表的函数,一切正常!
    • @ZacharyJacobi 我的经验是,混合承诺和回调有时很棘手,因此最好采用一种解决方案(对于您自己的代码;使用回调的第三方代码通常可以通过以下方式转换为承诺使用类似蓝鸟的promisifyAll)。 Mocha 可以原生处理 Promise,非常棒。
    • 模块中的大部分代码都在使用回调。我正在合并两个独立的代码库,所以我会做一个说明以确保坚持一个解决方案——可能是回调。感谢您的提醒!
    猜你喜欢
    • 1970-01-01
    • 2019-09-15
    • 2017-11-14
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多