mongoose memory leak attributed to jest

UPDATED 2020-09-14

I've encountered an issue with a test case I wrote. While the testcase passes, it raises a complaint about improper teardown and an open connection. Can anyone help identify the problem:

Approach to Solving the Issue - Memory Leak

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection> = async MONGO_DB_NAME => {
  if (conn == null) {
    conn = await createConnection(__MONGO_URI__, {
      dbName: MONGO_DB_NAME,
      bufferCommands: false,
      bufferMaxEntries: 0,
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true
    });
  }
  return conn;
};

const MONGO_DB_NAME = 'mongo-test';
let db: Connection;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async done => {
    db = await getConnection(MONGO_DB_NAME);
    done();
  });
  afterAll(async done => {
    if (conn) {
      await db.dropDatabase();
      await conn.close();
    }
    done();
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

Error:

A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --runInBand --detectOpenHandles to find leaks.

Simplifying the code doesn't solve the issue:

Another Attempt - Memory Leak

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection> = async MONGO_DB_NAME => {
  if (conn == null) {
    conn = await createConnection(__MONGO_URI__, {
      dbName: MONGO_DB_NAME,
      bufferCommands: false,
      bufferMaxEntries: 0,
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true
    });
  }
  return conn;
};

const MONGO_DB_NAME = 'mongo-test';
let db: Connection;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
    console.log('db = ', db);
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

The problem persists even when trying it another way:

Alternative Approach - Memory Leak

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const getConnection: (MONGO_DB_NAME: string) => Promise<Connection | null> = MONGO_DB_NAME =>
  new Promise(resolve => {
    if (conn == null) {
      conn = createConnection(__MONGO_URI__, {
        dbName: MONGO_DB_NAME,
        bufferCommands: false,
        bufferMaxEntries: 0,
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true
      });
      conn.on('connected', () => {
        console.log('connection established');
        resolve(conn);
      });
    }
    resolve(conn);
  });

const MONGO_DB_NAME = 'mongo-test';
let db: Connection;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
    console.log('db = ', db);
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

This new approach also presents the same issue:

Finding a Solution - Memory Leak

import mongoose from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: typeof mongoose;

const getConnection: (MONGO_DB_NAME: string) => Promise<typeof mongoose> = async MONGO_DB_NAME => {
  if (!conn) {
    conn = await mongoose.connect(__MONGO_URI__, {
      dbName: MONGO_DB_NAME,
      // bufferCommands: false,
      // bufferMaxEntries: 0,
      // useNewUrlParser: true,
      // useUnifiedTopology: true,
      // useCreateIndex: true
    });
  }
  return conn;
};

const MONGO_DB_NAME = 'mongo-test';
let db: typeof mongoose;

describe('mongo - connection test to ensure setup teardown', () => {
  beforeAll(async () => {
    db = await getConnection(MONGO_DB_NAME);
    console.log('db = ', db);
  });
  it('true = true', () => {
    expect(true).toBe(true);
  });
});

Answer №1

the final solution - credit goes to @EstusFlask

establishMongoConnection.ts

import { Connection, createConnection } from 'mongoose';
import __MONGO_URI__ from './__MONGO_URI__';

let conn: Connection | null = null;

const fetchConnection: (MONGO_DB_NAME: string) => Promise<Connection | null> = MONGO_DB_NAME =>
  new Promise(resolve => {
    if (conn == null) {
      conn = createConnection(__MONGO_URI__, {
        dbName: MONGO_DB_NAME,
        bufferCommands: false,
        bufferMaxEntries: 0,
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true
      });
      conn.on('connected', () => {
        resolve(conn);
      });
    }
    resolve(conn);
  });

export default fetchConnection;

mytest.test.ts

import { Connection } from 'mongoose';
import fetchConnection from './establishMongoConnection';

let db: Connection | null;

const MONGO_DB_NAME = 'mongo-test';
const collectionName = 'users';

describe('mongodb - testing connection setup and teardown', () => {
  beforeAll(async () => {
    db = await fetchConnection(MONGO_DB_NAME);
  });
  afterAll(async () => {
    if (db) {
      await db.dropDatabase();
      await db.close();
    }
  });
  it('should insert a document into the collection', async () => {
    if (db) {
      const users = db.collection(collectionName);

      const mockUser = { _id: 'some-user-id', name: 'John' };
      await users.insertOne(mockUser);

      const insertedUser = await users.findOne({ _id: 'some-user-id' });
      expect(insertedUser).toEqual(mockUser);
    }
  });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for resolving the error message "EADDRINUSE: address already in use" during integration tests

I recently started learning Node.js through an online course on Udemy. While running integration tests multiple times, I encountered an issue with listen EADDRINUSE: address already in use :::4000. The first run is successful, but subsequent runs result in ...

"Unlocking the versatility of Ramda by utilizing IfElse for passing additional parameters effectively

For my NodeJS project utilizing express and mongoose, I made the decision to incorporate RamdaJS as a way to delve into functional programming. I have implemented two pre-save hooks as follows: UserSchema.pre('save', async function (next) { ...

Is it possible to devise a universal click handler in TypeScript that will consistently execute after all other click handlers?

In my ReactJS based application written in TypeScript, we have implemented various click handlers. Different teams contribute to the application and can add their own handlers as well. The challenge we face is ensuring that a specific global click handler ...

Issues encountered: HTTP status code 404 received when making a PUT request with Node.js (express), Angular, and MongoDB

I've hit a roadblock trying to understand how to update my data ("Post") in MongoDB (using Mongoose, MongoDB, Node, Express, and Angular 9.1.1). I have no issues with POST and DELETE requests, but I can't seem to pinpoint the problem with PUT. A ...

Craft a unique typings file tailored to your needs

After recently creating my first published npm package named "Foo", I encountered some difficulties while trying to consume it in a TypeScript project. The tutorials on how to declare modules with custom typings were not clear enough for me. Here are the k ...

Varieties of data classifications for the information obtained from supabase

1 I'm encountering an issue while attempting to define the data types from Supabase. I received an error message stating: "type '{ id: string; title: string; capacity: number | null; start_date: Date | null; start_time: string | null; end_ ...

Testing React components using Jest and Enzyme can be smooth sailing, but when it comes to testing

I am new to React and seeking guidance for the following issue. I have a component: const Login: FunctionComponent = () => { const history = useHistory(); //extra logic that may not be necessary yet return ( <div> ...

Storing data using mongoose does not alter the existing information

I encountered an issue with my code while trying to update an object fetched from a MongoDB. The object contains a map with an array, and I am pushing new values to that array within the map successfully. However, even though the object itself reflects the ...

I am facing an issue with updating the mat-table after pushing values to a

I have a uniqueFormGroup with UniqueFormArray and a special-table that displays the array. When I add new uniqueFormGroup to UniqueFormArray, the special-table doesn't add new row. I was attempting to implement trackBy, but I am unsure of where (and ...

What is the best approach for retrieving specific data from MongoDB in a Node.js application using the GET method?

I have a variety of collections stored on a remote MongoDB server. My objective is to retrieve a specific collection based on the city name. I am currently using POSTMAN to mimic a GET request, but it seems that a different GET method is being triggered: { ...

I encountered an error stating "Buffer is not defined" originating from the Deode/Encode Stream Bundle.js script, not from my own code

I've encountered a major issue while attempting to update my npm project to webpack 5, and now I'm left with just one persistent error: bundle.js:1088566 Uncaught ReferenceError: Buffer is not defined at bundle.js:1044980:24 ...

Understanding File Reading in Angular/Typescript

I'm currently developing an app similar to Wordle and I'm facing an issue with reading words from a file. Here's what I tried: import * as fs from 'fs'; const words = fs.readFileSync('./words.txt', 'utf-8'); con ...

When logging `self`, the output field is present; however, attempting to log `self.output` results in

I've encountered a strange issue. When I use console.log(self) to log the variable, it shows that the output key is set and contains all the values. However, if I try to log console.log(self.output), it returns undefined. Does anyone know why this is ...

Improving the App() function in React and Typescipt

When working on my React/Typescript app, I encountered a challenge with the length of the code in one of the sections. Despite watching tutorials and searching for solutions, I couldn't find a clear way to refactor it. The specific issue is with refa ...

Using TypeScript TSX with type parameters

Is it possible to define type parameters in TypeScript TSX syntax? For instance, if I have a class Table<T>, can I use something like <Table<Person> data={...} /> ...

Unable to locate the next/google/font module in my Typescript project

Issue With Import Syntax for Font Types The documentation here provides an example: import { <font-name> } from 'next/google/font'; This code compiles successfully, but throws a "module not found" error at runtime. However, in this disc ...

The act of exporting an enum from a user-defined TypeScript path leads to the error message "Module not

I have set up a custom path as explained in this particular discussion. "baseUrl": ".", "paths": { "@library/*": [ "./src/myFolder/*" ], } Within this module, I am exporting an Enum. export enum EN ...

What is the correct way to use Observables in Angular to send an array from a Parent component to a Child

Initially, the task was to send JSON data from the parent component to the child component. However, loading the data through an HTTP request in the ngOnInit event posed a challenge as the data wasn't being transmitted to the child component. Here is ...

What could be causing the TypeScript exhaustive switch check to malfunction?

How come the default case in the switch statement below does not result in an exhaustive check where 'item' is correctly identified as of type 'never'? enum Type { First, Second } interface ObjectWithType { type: Type; } c ...

Utilizing Next.js to Import a Function from a Path Stored within an Environment Variable

I'm having trouble importing a function whose path is stored in an environment variable Current import statement: import { debug } from '../lib/site-A/utils' Expected import statement: import { debug } from process.env.DEBUG_PATH In my ...