Question

I am having trouble writing tests for my objects using mocha. The code appears to work in practice but during my tests, database updates are happening later than expected. During test setup I insert a few records into a collection. In the teardown I clear the collection. When I search for a known record I get zero results unless I recursively invoke the callback function (as shown in the code below).

Everything is written asynchronously. The setup function returns all the records. Somehow it seems that the data is not refreshed quickly enough. Can anyone advise if I am approaching this correctly with the recursive loop?

var myclass = require('myclass')
var mongoose = require('mongoose');
var should = require('should');
mongoose.connect('mongodb://localhost/myDbTests');
mongoose.connection.on('error', console.error.bind(console, 'connection error:'));

describe('Test my collection.', function () {
    beforeEach('load dummy data into the database', function (done) {
        myclass.load_data(dummyData, function (count) {
            count.should.be.greaterThan(5);
            done();
        });
    });
    afterEach('clear the database', function (done) {
        myclass.model.remove({}, function() {
            done();
        });
    });

    it('check that a known record exists database', function (done) {
        var keep_checking = function (td) {
            if (!td) {
                myclass.get_record('MYRECORD', keep_checking);
            } else {
                td.should.have.property('category', 'someCategory');
                done();
            }
        }
        keep_checking(0);
    });

});

My load_data is:

var _load_data = function (data, callback) {
    data.forEach(function (d) {
        var rec = new _model(d);
        rec.save(function(err, res) {
            if (err) return console.error(err);
        });
    });
    callback(data.length);
};
Was it helpful?

Solution 2

I was not loading the data correctly. Mongoose does not allow multiple record insertion so I had used a synchronous .forEach loop to save each object. A better way to do, and hence my solution, is the following:

var _load_data = function (data, callback) {
    var total = data.length,
        count = 0;

    function saveAll() {
        var doc = data[count];
        var rec = new _model(doc);
        rec.save(function(err, res) {
            if (err) {
                throw err;
            }
            if (count !== total) {
                count += 1;
                saveAll();
            } else {
                callback(count);
            }
        });
    }
    saveAll();
};

OTHER TIPS

You should wait until the database connection is open to run your tests. I achieve that in my tests with the before hook which runs before any test (and before beforeEach as well):

before(function(done) {
  mongoose.connection.once('open', done);
}

That will prevent anything from being run before the database connection is open.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top