Etienne Prothon
Etienne Prothon

Reputation: 1082

Timeout using mongoose createConnection for test with mocha

I have a problem with the mongoose.createConnection function, here is my code for the tests:

"use strict";
// connect to mongodb://localhost/node_marque_test
// empty database before each test

let mongoose = require('mongoose'),
    expect = require('chai').expect,
    // use a specific base for test purposes
    dbURI = 'mongodb://localhost/node_marque_test',
    Marque = require('../lib/marque.js');

before(function(done){
  // connect to db
  let connection = mongoose.createConnection(dbURI);
  // remove all documents
  connection.on('open', function(){

    Marque.remove(function(err, marques){
      if(err){
        console.log(err);
        throw(err);
      } else {
        // console.log('cleaning marques from mongo');
        done();
      }
    })
  })
})
afterEach(function(done){
  Marque.remove().exec(done);
})

describe('an instance of Marque', ()=>{
  let marque;
  beforeEach((done)=>{
    marque = new Marque({name: 'YAMAHA'})
    marque.save((err)=>{
      if(err){throw(err);}
      done();
    })
  })
  it('has a nom', ()=>{
    expect(marque.name).to.eql('YAMAHA');
  })

  it('has a _id attribute', ()=>{
     expect(marque).to.have.property('_id')
  })
})

And here is the code of the Marque object:

"use strict";
let mongoose = require('mongoose'), Schema = mongoose.Schema;

// Schema definition with some validation
let marqueSchema = Schema({
    name: { type: String, required: true}
});

// compile schema to create a model
let Marque = mongoose.model('Marque', marqueSchema);

// custom validation rules
Marque.schema.path('name').validate(name_is_unique, "This name is already taken");

function name_is_unique(name,callback) {
    Marque.find({$and: [{name: name},{_id: {$ne: this._id}}]}, function(err, names){
        callback(err || names.length === 0);
    });
}

module.exports = mongoose.model('Marque');

So when i run npm test i got this error:

  1) "before all" hook

  0 passing (2s)
  1 failing

  1)  "before all" hook:
     Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

But if i replace

// connect to db
let connection = mongoose.createConnection(dbURI);
// remove all documents
connection.on('open', function(){

By

// connect to db
mongoose.connect(dbURI);
// remove all documents
mongoose.connection.on('open', function(){

Everything works and the test pass :

  an instance of Marque
    ✓ has a nom
    ✓ has a _id attribute


  2 passing (65ms)

The problem is that i need to do multiples tests so i can't use mongoose.connect (else i got Error: Trying to open unclosed connection. )

So how can i use createConnection to connect to mongoose inside my tests ?

Thanks for your help :)

Upvotes: 5

Views: 1320

Answers (1)

ppsreejith
ppsreejith

Reputation: 3458

To fix this, we need to register the model schema on the connection instance. i.e use connection.model instead of mongoose.model. From here

you need to always reference that connection variable if you include a registered model, otherwise, if you use mongoose to load the model, it will never actually talk to your database.

To address your problem, first pass the connection instance to marque.js.

...
let connection = mongoose.createConnection(dbURI);
Marque = require('../lib/marque.js')(connection);
...

and in marque.js:

"use strict";
let mongoose = require('mongoose'), Schema = mongoose.Schema;

// Schema definition with some validation
let marqueSchema = Schema({
    name: { type: String, required: true}
});

module.exports = function(conn) {
    // compile schema to create a model. Probably should use a try-catch.
    let Marque = conn.model('Marque', marqueSchema);

    // custom model validation code here
    // ...

    return conn.model('Marque');
}

Upvotes: 1

Related Questions