Mongoose / Mocha testing

Hello FCC,

I’m working on the url shortener backend challenge and I am stumped with testing one of my functions I’ve written. I’ve written a function createShortUrl() which connects to the db, generates a random string, creates a new url model and calls .save on the object. The function then disconnects from the db and calls the callback. The code looks like this.

function createShortUrl(longUrl, cb){
  mongoose.connect('mongodb://localhost/test', function(err){
    let randShort = sm.randomString();
    let url = new Url({
      long_url: longUrl,
      short_url: randShort
    });

    url.save(function(err){
      if (err) throw err;
      mongoose.disconnect();
      cb();
    }); 
  });
}

I’m writing my tests with mocha and I CANNOT get a test to pass for this function. My test case looks like this

describe('the createShortUrl function', function(){
  it('should create a long:short entry in the db', function(done){
    this.timeout(10000);
    let longUrl = 'http://www.reddit.com';
    url.createShortUrl(longUrl, function(){
      Url.find({}, function(err, docs){ //this Url is a model object
        if (err) throw err;
        expect(docs[0].long_url).to.eql(longUrl);
        expect(typeof docs[0].short_url).to.eql('string')
        expect(docs[0].short_url).to.have.length(5);
        done();
      });
    });
  });
});

when I run my tests with npm test the test does not pass. the error message says Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

I originally thought that this may be because when I call the createShortUrl() function I close the connection to the database, so I’ve also tried to open the connection before calling Url.find() like this:

describe('the createShortUrl function', function(){
  it('should create a long:short entry in the db', function(done){
    this.timeout(10000);
    let longUrl = 'http://www.pivotalvoices.com';
    url.createShortUrl(longUrl, function(){
      mongoose.connect('mongodb://localhost/test'); //reconnet to db before calling Url.find
      Url.find({}, function(err, docs){
        if (err) throw err;
        expect(docs[0].long_url).to.eql(longUrl);
        expect(typeof docs[0].short_url).to.eql('string')
        expect(docs[0].short_url).to.have.length(5);
        done();
      });
    });
  });
});

When this code is run I get a different error message:
Uncaught Error: Trying to open unclosed connection.

What’s curious is that in both cases my data is saved correctly to the database — I just can’t get the test to pass and it is driving me crazy. I’ve mulled it over for hours.

Can anyone offer some help with this?

Thanks very much!

Remove mongoose.disconnect();

As a rule of thumb you should have

mongoose.connect('mongodb://...');

somewhere at the beginnning of your entry file and you should not do any connects/disconnects later. Mongoose does connection management itself.

1 Like

This worked! Thank you so much @jenovs for your help.