Express did not cause Jest to exit one second after completing the test run

I'm currently utilizing JEST to conduct unit tests on my express routes.

When I run the yarn test, all of my test cases pass successfully. However, an error occurs:

Jest did not exit one second after the test run has completed.

This typically indicates that there are asynchronous operations lingering in your tests. You may want to consider running Jest with `--detectOpenHandles` for troubleshooting.

Even though I included async and done, I still encounter the above error.

Below is the code snippet from my spec file. Any assistance would be greatly appreciated.

routes.spec.ts

const request = require('supertest');
describe('Test the root path', () => {
  const app = require('./index');

  test('GET /gql/gql-communication-portal/release-notes', async (done) => {
    const response = await request(app).get('/gql/gql-communication-portal/release-notes');
    expect(response.status).toBe(200);
    done();
  });
});

Answer №1

This snippet of code helped me resolve my issue:

beforeAll(done => {
  done()
})

afterAll(done => {
  // Ensuring proper closure of the DB connection for successful Jest exit.
  mongoose.connection.close()
  done()
})

Answer №2

This line has been included in the package.json file.

It was successful for me.

jest --runInBand --detectOpenHandles --forceExit

Answer №3

My situation involved a unique issue where I needed to close the connection to the server itself while testing routes using supertest.

afterAll(done => {
    server.close();
    done();
});

To handle this, you can start the server in a beforeAll block and then close it in an after all block:

beforeAll(() => {
   server = app.listen(someRandomNumberHere); // Using a random number helps avoid conflicts when running tests in parallel
})

afterAll(() => {
   server.close()
})

In case you need more clarity, here are some additional details:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});
module.exports = app;

To boot up your application, import it in your index.js or equivalent file like this:

const app = require('./app'); // Assuming app.js is in the same directory

If you encounter a different scenario, this issue may provide some insights for you.

Answer №4

Inserting

jest.useFakeTimers();

at the start of my test suite resolved the issue.

It could be related to timers set within components that are part of the rendering process (such as throttled buttons, mocks, etc.).

Answer №5

In my setup, I make sure to separate the app.listen() function from the main app logic in Express. This way, the main app file can simply end with an export statement.

// app.js
module.exports = app;

Then, I create a separate file specifically for listening to the port.

// server.js
const app = require('./app')
app.listen(...)

If you only import the main app file (such as app.js) in your tests, it should work without any additional configuration. Just remember to adjust the starting point of your Express app to use server.js instead.

Answer №6

Encountering a similar problem, I made an adjustment in my package.json file by including the line

"test": "jest --detectOpenHandles"
and executing npm test --detectOpenHandles. To my relief, the error message did not appear this time. It may be worth giving this approach a try.

Answer №7

I found a solution that worked perfectly for my issue.

const mongoose = require('mongoose');
    afterAll(async(done) => {
  // Making sure to close the DB connection so Jest can exit successfully.
  try {
    await mongoose.connection.close();
    done()
  } catch (error) {
    console.log(error);
    done()
  }
  // done()
})

Answer №8

Feel free to give this a shot

"experiment": "jest --runInBand --force-exit"

Answer №9

When working with Firebase, the cleanup() function had to be invoked

import {
    assertFails,
    assertSucceeds,
    initializeTestEnvironment,
    RulesTestEnvironment,
} from "@firebase/rules-unit-testing";
import { doc, setDoc } from "firebase/firestore";

it('adds a new user document in firebase', async () => {
    const testEnv = await initializeTestEnvironment({
        projectId: "appname-test",
        firestore: {
            host: 'localhost',
            port: 8088
        }
    });

    const alice = testEnv.authenticatedContext("alice");

    await assertSucceeds(setDoc(doc(alice.firestore(), "users", "alice"), {
        fname: "Alice",
        lname: "Wonderland",
        dob: "18/01/1999",
        email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="72131e1b111732170a131f021e175c111d1f">[email protected]</a>"
    }));

    return await testEnv.cleanup();
});

Answer №10

When working with NestJs applications, you may encounter a scenario like this:

app = moduleFixture.createNestApplication();
await app.init();

To properly handle this in your test file, simply include the following:

afterAll(done => {
    app.close()
    done()
})

If you prefer using async functions, you can also do it this way:

afterAll(async() => {
    await app.close()
})

Answer №11

New 2023 One-Liner with a Clean and Simple Design

This one-liner was inspired by Saleh's answer, but it eliminates the need to use "done."

To complete your test file, simply add the following code snippet at the end:

afterAll(() => mongoose.connection.close())

Answer №12

The issue typically arises when there are pending asynchronous operations that have not completed before jest attempts to exit.

In app.js, export the app and server:

const express = require('express');
const app = express();

const server = app.listen(3000, () => {
  console.log('App is listening on port 3000');
});

module.exports = { app, server };

In test.js:

const request = require('supertest');
const { app, server } = require('../app');

describe('Monitoring Routes', () => {

    afterAll(() => {
        server.close();
    });

    it('should return status 200 for /path1/path2', async () => {
        const response = await request(app).get('/path1/path2');
        expect(response.status).toBe(200);
    });
});

Answer №13

I encountered a similar issue while using the pg module in my NodeJS Express application. I thought I'd share this for others who are using the same technology stack, in case it could be of assistance to them.

Essentially, when using supertest, it creates a server connection that may result in the TCPSERVERWRAP error if not properly closed. This closure is necessary after each test, regardless of whether async/await or the jest done callback is used. Additionally, the database connection needs to be closed as well, which I achieved by mocking it.

I was able to resolve the error by closing the server connection and mocking the pg module together.

products.tests.ts

import request from 'supertest'
import { Pool } from 'pg'
import app from '../app'
import type { Server } from 'http'

jest.mock('pg')

const { ROUTE_VERSION = '/v1' } = process.env
const route = (path: string) => [ROUTE_VERSION, path].join('')
const pool = new Pool()
let server: Server

beforeEach(() => {
   server = app.listen(4000)
})

afterEach(() => {
   server.close()
})

describe('GET /products', () => {
   it('returns array of products', async () => {
      await request(server)
         .get(route('/products'))
         .expect(200)
         .expect((res) => {
            expect(pool.query).toBeCalledTimes(1)
            expect(res.body).toBeInstanceOf(Array)
            expect(res.body).not.toHaveLength(0)
         })
   })
})

UPDATE: It is important to use beforeEach and afterEach to close the server after EACH test, otherwise, it will remain open.

UPDATE 2: Ensure to utilize async/await when working with request to wait for its completion, as it is asynchronous and will not finish unless awaited.

Answer №14

I encountered a similar issue when I forgot to close the database connection after running all the test cases. To resolve this, you can modify jest.config.js and create a new file in the root directory that will handle closing the database connection globally.

In your jest.config.js file, include the following in the module.exports:

module.exports = {
   setupFilesAfterEnv: ['<rootDir>/src/runAfterAllTests.ts'],
}

Next, add runAfterAllTests.ts to the src folder.

Inside runAfterAllTests.ts, write code to globally close the db connection. If using mongodb, it could look something like this:

import { client } from './database/connect';

global.afterAll(async () => {
  await client.close();
});

Implementing this solution will ensure that the database connection is properly closed after all tests, resolving the issue.

Answer №15

One issue I encountered was forgetting to properly close the Sequelize ORM at the end of testing within the afterAll function callback.

Here is the snippet of the code causing the problem:

afterAll((done) => {
    MatrixTableHeaderCol.destroy({
        where: {},
        force: true
    }).then(() => {
        done();
    });
});

Answer №16

If you are encountering issues while working with Firebase, make sure to remember to include a call to testEnv.cleanup()

let testEnv;

beforeAll(async () => {
  // To avoid expected rules rejections from Firestore SDK, set the log level to "error". Unexpected rejections will still cause errors.
  setLogLevel("error");
  testEnv = await initializeTestEnvironment({
    projectId: projectId,
    firestore: {
      rules: readFileSync("firestore.rules", "utf8"),
      host: "127.0.0.1",
      port: 8080,
    },
  });
});


afterAll(async () => {
    await testEnv.cleanup();
})

Answer №17

Dealing with a similar issue, I encountered the problem while using knex.js. To resolve it, I made some adjustments in my code. In the index.ts file, I included:

const PORT = process.env.PORT || 3000;
if (process.env.NODE_ENV !== "test") {
  app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
}

Subsequently, in my .test.ts file, right before initiating the test, I implemented the following changes:

import request from "supertest";
import app from "@/index";
import { Server } from "http";
import db from "../../db";

let server: Server;

beforeAll((done) => {
  server = app.listen(process.env.PORT || 3000, () => {
    done();
  });
});

afterAll((done) => {
  db.destroy(); // This action facilitates closing the db connection
  server.close(done);
});

The 'db' variable corresponds to the configuration of knex.js.

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

Display a React component according to the user's input

Within the first (parent) div, there is an underlined message stating: "This JSX tag's 'children' prop expects a single child of type 'ReactNode', but multiple children were provided.ts(2746)". import A from './components/A&ap ...

Compare the values of properties in an array with those in a separate array to filter in Angular/TypeScript

There are two arrays at my disposal. //1st array tasks.push({ ID: 1, Address: "---", Latitude: 312313, Longitude: 21312 }); tasks.push({ ID: 3, Address: "---", Latitude: 312313, Longitude: 21312 }); //2nd array agentTasks.push({ID:2,AgentID: 2,TaskID:1}); ...

Tips on adding an item to the array field of a model in Mongoose

I have 2 collections like this: const vocaSchema = { word: String, type: String, meaning: String, sente: String, semean: String, sug: String }; const Voca = mongoose.model('Voca', vocaSchema); const setVocaSchema = { ...

Storing Data in Arrays with Node.js and Express: The Guide to Preventing Rendering in a Web Browser's DOM

My Node.js route in Express is functioning properly by retrieving data from a database. app.get('/getdata/:key', function(req, res){ console.log("Search key(s):", req.originalUrl.split("/")[2]); keys = req.originalUrl.split("/")[2] Keys ...

Module express not found

When attempting to run my express application, I encountered the following error message: module.js:471 throw err; ^ Error: Cannot find module './controllers' This is the content of my app.js file: const express = require('e ...

Creating a collapsible sidebar feature in Angular 2

Currently in the process of converting an HTML jQuery AdminLTE dashboard to Angular 2 In the past, I would hide and show the sidebar using toggle() in jQuery. Now I'm wondering how to achieve the same functionality in Angular 2. I am utilizing the ...

Reviewing for the presence of "Undefined" in the conditional statement within Transpiled Javascript code for

While perusing through some transpiled Angular code, I came across this snippet: var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { I'm puzzled by the usage of undefined in this context. Can an ...

Unable to access attributes of an object that has not been defined (referencing 'providers')

https://i.sstatic.net/9Ntvd.png When I try to import web3 version 1.2.11, I am using the following code in TypeScript: import Web3 from 'web3' const readonlyProvider = new Web3.providers.HttpProvider(providerURL) However, after compiling it, ...

An error has occurred in React with a nested JSON object, suggesting that it may actually

I encountered an interesting error with my React file using Axios. While the data retrieval from my post works fine, I am facing a problem when trying to display all posts on one page. Despite my efforts to find a solution, I have not been successful. Bel ...

Tips for utilizing BLOB data type in Sequelize migrations

Lately, I have embarked on using nodejs and sequelize to develop a sample application. Within my application, there are users, and while trying to add dummy data through seeders in sequelize, I encountered a challenge when it came to adding a profile pictu ...

What is the most effective approach for addressing errors in both the server and client sides while utilizing nodejs and express?

Seeking the most effective approach for handling errors in a response - request scenario. Here is an example of a route that receives a request: app.get('/getInfo', function (req, res, next) { let obj = {} try { obj = { ...

Extracting type from a variable in TypeScript

class A { public static find(): Query{ const f = () => new this(); return new Query(f); } } class B extends A { } class C extends A { } class Query { private readonly entity: () => A; constructor(entity: () => A) { ...

Troubleshooting Problem with Next.js 13 Integration, Supabase, and Server Actions in layout.tsx

I'm currently developing a Next.js 13 application and experimenting with managing user authentication through Supabase. I've encountered some challenges when attempting to verify if a user is logged in using an asynchronous function within my lay ...

Retrieving data from an API using VUEJS3 and Typescript

I am facing an issue with displaying data in my template. When I try to do so, the screen remains blank. I am using Vue.js 3 with TypeScript and I am fairly new to this technology. <template> <div> <img :src="datas[0].imag ...

When using Webpack, there may be difficulties resolving relative path import of express static files

I am currently developing an Outlook add-in with an Express server running. To ensure compatibility with Outlook Desktop, I need to transpile JavaScript to ES5 using Webpack. Below is the simplified structure of my project: /public /javascripts ssoAu ...

Expressing node.js: Understanding URL mapping

router.get("customer/:customerId", async (request, response) => { console.log("Retrieve customer data based on specific customer ID") } router.get("customer/regions", async (request, response) => { ...

Is there a way to swap out the current URL in TypeScript without causing a page refresh?

Is there a way to update the URL of a page in Angular 11 without causing a refresh? I have tabs on my page, and when a tab is clicked, I want to add the name of the tab with a '#' prefix to the current URL. I've tried implementing this by c ...

Create a function that takes in an array of strings and outputs a record containing a unique key for each string in the array

Looking to create a function that takes an array of strings as input and returns an object with a key for each string in the input array? Here is an example of how this can be implemented: const getMyObject = (...keys: string[]) => keys.reduce((object, ...

Ensure to verify the `childProperty` of `property` within the `req.checkBody

When working with Node.js, a common practice is to use code like the following: req.checkBody('name', 'Group name is required.').notEmpty(); In a similar fashion, I have implemented something along these lines: req.checkBody('pa ...

What key Angular 2 considerations should be taken into account when developing an Angular 1 application?

I am facing the task of rewriting a large and complex web application in Angular 1.x. As I am not yet familiar with Angular 1.x, I am looking for ways to prepare for a potential rewrite in Angular 2.x. Some considerations include: Code structure: Is t ...