Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timeout when attempting to connect to mongo from jest unit tests

I want to write some unit tests with jest and mongoose to validate data interaction with mongo.

I don't want to mock mongoose here because I specifically want to validate the way that mongo documents are created/modified/handled.

package.json is configured to leave node modules unmocked:

{
  "jest": {
    "unmockedModulePathPatterns": [
      "node_modules"
    ]
  }
}

In my actual test, I have set up a beforeAll() hook to take care of connecting to mongo:

const mongoose = require('mongoose');

describe('MyTest', () => {

  beforeAll((done) => {
    mongoose.connect('mongodb://127.0.0.1:27017/test');

    let db = mongoose.connection;

    db.on('error', (err) => {
      done.fail(err);
    });

    db.once('open', () => {
      done();
    });
  });

  it('has some property', () => {
    // should pass but actually never gets run
    expect(1).toBe(1);
  });
});

Here's the output:

/usr/local/bin/node node_modules/jest-cli/bin/jest.js --verbose
Using Jest CLI v0.10.0, jasmine2
 FAIL  src/lib/controllers/my-controller/__tests__/my-test.js (5.403s)
MyTest
  ✕ it has some property

MyTest › it has some property
  - Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
        at Timer.listOnTimeout (timers.js:92:15)
1 test failed, 0 tests passed (1 total in 1 test suite, run time 5.903s)

Process finished with exit code 1

The test times out every time because done() is never called in the beforeAll() hook - no errors thrown nor anything printed to console. I can place breakpoints in the beforeAll() hook to validate the code is being run. It appears that mongoose is hanging whilst attempting to open a connection to Mongo, and then the jest tests are timing out.

When I'm running similar code outside of the jest environment, it connects as expected (nigh on instantly). Suspecting that it could be causing problems, I've experimented with disabling jest's automock feature completely, but the behaviour remains unchanged.

I imagine I've missed something incredibly obvious... any ideas what could be going on?

  • jest-cli v. 0.10.0
  • mongoose v. 4.4.11

Updates:

  • Tried replacing ES6 arrow function syntax with plain function(done) {}. No difference.
  • Tried making the test async by passing done parameter, and calling it on test completion. No difference.
  • Tried calling mongoose.connect() after the declaration of error and connected event handlers
  • Tried commenting out all mongoose-related code to check that the beforeAll() hook is working correctly - it is.
like image 832
jayp Avatar asked Apr 05 '16 10:04

jayp


1 Answers

Jest-jasmine is different from Jasmine.
The syntax you used actually belongs to Jasmine 2.0+, not Jest-jasmine. So if you want to continue to use jest, you have to look into jest docs to find the answer.
Even more, "beforeAll" is not a standard jest injected variables, see jest api.

I got your code run with Jasmine 2.3.4, it runs just fine. I tried Promise/pit in jest to finish this job but failed.

First, install jasmine.

npm install -g jasmine
mkdir jasmine-test  
cd jasmine-test
jasmine init
jasmine examples
touch spec/mongodbspec.js

Here is my directory structure:

fenqideMacBook-Pro:jasmine-test fenqi$ ls -R
.:
spec/

./spec:
mongodbspec.js  support/

./spec/support:
jasmine.json

Then, edit spec/mongodbspec.js, I just add one line " 'use strict'; " to your code.

'use strict';

const mongoose = require('mongoose');

describe('MyTest', () => {

  beforeAll((done) => {
    mongoose.connect('mongodb://127.0.0.1:27017/test');

    let db = mongoose.connection;

    db.on('error', (err) => {
      done.fail(err);
    });

    db.once('open', () => {
      done();
    });
  });

  it('has some property', () => {
    // should pass but actually never gets run
    expect(1).toBe(1);
  });
});

Last, run 'jasmine' :

fenqideMacBook-Pro:jasmine-test fenqi$ jasmine
Started
.


1 spec, 0 failures
Finished in 0.023 seconds
like image 180
sel-fish Avatar answered Nov 11 '22 04:11

sel-fish