jest-mongodb icon indicating copy to clipboard operation
jest-mongodb copied to clipboard

Usage with jest globalSetup and globalTeardown

Open justin-schroeder opened this issue 5 years ago • 6 comments

Awesome module!

We're running fine with the current implementation, however, one small sticking point is that we have to perform a new connection and disconnection within every jest block. It would be awesome if we were able to use a globalSetup and globalTeardown to connect/disconnect our client (mongoose) to the database once.

Unfortunately, when I do this, the process.env.MONGO_URL is undefined:

module.exports = async function globalSetup() {
  await mongoose.connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
  });
};

I suspect this is because the setup and teardown might run before the preset? Any thoughts as to a way around this limitation?

justin-schroeder avatar Jun 29 '20 16:06 justin-schroeder

This is achievable by calling setup directly:

const mongoSetup = require('@shelf/jest-mongodb/setup');
module.exports = async config => {
  await mongoSetup();
  const url = process.env.MONGO_URL;
  if(url == null) {
    throw new Error("MONGO_URL was not set");
  }
  // connect
}

chanced avatar Jul 08 '20 17:07 chanced

Confused @chanced. You're saying you can do this in jest’s globalSetup? Where do you use the mongoSetup() you described? Like I said in the original post, I'm able to connect just fine for each individual test suite, just not once globally which would be really nice.

justin-schroeder avatar Jul 09 '20 01:07 justin-schroeder

Yea. You should be able to, I believe. mongoSetup is just the variable name I assigned to require'@shelf/jest-mongodb/setup') which is the default export of https://github.com/shelfio/jest-mongodb/blob/master/setup.js#L10

Given your initial function, it would look like:


const mongoSetup = require('@shelf/jest-mongodb/setup'); 

module.exports = async function globalSetup() {
  await mongoSetup();
  // process.env.MONGO_URL is now set by
  // https://github.com/shelfio/jest-mongodb/blob/fcda766bfa433644a7383993467ccaa06dfea28b/setup.js#L26
  await mongoose.connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
  });
};

chanced avatar Jul 09 '20 02:07 chanced

I did as follows, but I am having trouble connecting to the database from my test files.

Here are the relevant files with their code. jest.setup.js

import mongoose from "mongoose";

const mongoSetup = require("@shelf/jest-mongodb/setup");

module.exports = async () => {
  await mongoSetup();

  global.__DB__await = mongoose
    .connect(process.env.MONGO_URL, {
      useNewUrlParser: true,
      useCreateIndex: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
    })
    .then(null, (err) => {
      console.log(
        `In-memory mongodb instance failed to initialize. Error: ${err}`
      );
    });
};

jest.teadown.js

import mongoose from "mongoose";

module.exports = async () => {
  await mongoose.connection.close();
};

jest.config.js

module.exports = {
 preset: "@shelf/jest-mongodb",
 globalSetup: "<rootDir>/server/__tests__/__utils__/jest.setup.js",
 globalTeardown: "<rootDir>/server/__tests__/__utils__/jest.teardown.js",
}

None of my tests that require a connection to mongodb to run successfully and pass. Running npm run test -- --detectOpenHandles reveals the following errors.

●  TCPSERVERWRAP

710 |       };
711 |       let response = await request(app)
> 712 |         .post("/api/users")
|          ^
713 |         .send(payload)
714 |         .set("Accept", "application/json");
715 |       expect(response.statusCode).toBe(200);

at Test.serverAddress (node_modules/supertest/lib/test.js:48:35)
at new Test (node_modules/supertest/lib/test.js:34:14)
at Object.post (node_modules/supertest/index.js:28:14)
at server/__tests__/controllers/user.controller.test.js:712:10

All tests exit with TCPSERVERWRAP. npm run test is test: "jest" in the package.json file.

I have tried the block of async code in the jest.setup.js and jest.teadown.js files in a beforeAll() and afterAll() embedded into each the test files and it works. All tests pass when the db connection originates from the test files themselves.

Any guidance is highly appreciated.

RashiqAzhan avatar Jan 25 '22 13:01 RashiqAzhan

Yea. You should be able to, I believe. mongoSetup is just the variable name I assigned to require'@shelf/jest-mongodb/setup') which is the default export of https://github.com/shelfio/jest-mongodb/blob/master/setup.js#L10

Given your initial function, it would look like:

const mongoSetup = require('@shelf/jest-mongodb/setup'); 

module.exports = async function globalSetup() {
  await mongoSetup();
  // process.env.MONGO_URL is now set by
  // https://github.com/shelfio/jest-mongodb/blob/fcda766bfa433644a7383993467ccaa06dfea28b/setup.js#L26
  await mongoose.connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
  });
};

i still have the same error; can't connect to the database and then timeout error

finalight avatar May 16 '22 02:05 finalight

Not clear if this will work due to https://mongoosejs.com/docs/jest.html#globalsetup-and-globalteardown

khivi avatar Jul 15 '22 16:07 khivi