Why doesn't jasmine-node mongoose test wait, as expected?

605 Views Asked by At

I am writing a simple app that saves and looks up locations. I'm using mongoose and jasmine-node.

User CRUD test work as expected. However, I created the users individually to test different custom validations. I also start the tests by clearing the collection and re-loading all the users as a way to be sure all test data is good before launching into save/update/etc tests.

For locations, I am doing the same but I have several dozen locations and I wanted to load them using an array...and test the load along the way to be sure that it works fine.

If I only do one location, it works fine. More than one and they fail.

I know I'm missing some async related step here, but I'm either searching for the wrong terms or I'm too close to it now to see the fundamentally simple mistake I'm making here.

Versions:

  • mongoose: 3.6.16
  • jasmine-node: 1.11.0
  • mongodb: 2.4.5

Details The test...

it("creating location succeeds", function(done){

    for(var locIndex in testLocations) {
        locations.create(testLocations[locIndex], function(err, location){

            // console.log says location is undefined
            // unless there is only one location, then it works.

            expect(err ).toBeNull();
            expect(location.name ).toBe(testLocations[locIndex].name);
            done();
        });
    }
});

...and the create function from a separate file holding location related functions...

exports.create = function(location, cb){
    var newLocation = new Location(location);
    // console.log says we make it into here...

    newLocation.save(function(err, newLocation){
        // ...but we never make it in here, except when there's only one location
        if (err) {
            cb(err, null);
        } else {
            cb(null, newLocation);
        }
    });
};

...and some test locations...

var testLocations = [
    {
        "name" : "A Great Noodle Place",
        "street" : "1234 Elm Street",
        "city" : "Springfield",
        "phone" : "(123) 456-7890",
        "website" : "n00dlesrus.com",
        "district" : "Downtown"
    },
    {
        "name" : "Perfect Pizza Palace",
        "street" : "1234 Professor Ave",
        "city" : "Springfield"
        "phone" : "(321) 654-0987",
        "website" : "cheesegalore.com",
        "district" : "Uptown"
    }
]

Thanks!

1

There are 1 best solutions below

0
On BEST ANSWER

You're calling done() inside a loop. So it gets called in the first iteration. That's why it works when there's only 1. You could try using async, which will iterate over a list and call a final callback when finished:

it("creating location succeeds", function(done){

    async.each(Object.keys(testLocation), function(key, callback){
        locations.create(testLocations[key], function(err, location){
            expect(err).toBeNull();
            expect(location.name).toBe(testLocations[key].name);
            callback();
        });
    }, function(err) {
        done();
    });
});