ladjs / supertest

🕷 Super-agent driven library for testing node.js HTTP servers using a fluent API. Maintained for @forwardemail, @ladjs, @spamscanner, @breejs, @cabinjs, and @lassjs.
MIT License
13.75k stars 758 forks source link

Open handle keeps Jest from exiting ( TCPSERVERWRAP) #520

Open lucianonooijen opened 5 years ago

lucianonooijen commented 5 years ago

Error:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

● TCPSERVERWRAP

Env:

Testcode:

const request = require('supertest');
const app = require('../app');

describe('Test the status paths', () => {
    test('The GET / route should give status code 200', async () => {
        expect.assertions(1);
        const response = await request(app).get('/');
        expect(response.statusCode).toBe(200);
    });

    test('The GET /status route should give status code 200', async () => {
        expect.assertions(1);
        const response = await request(app).get('/status');
        expect(response.statusCode).toBe(200);
    });
});

Full console output:

 PASS  tests/app.test.js
  Test if test database is configured correctly
    ✓ Jest should create a test database (54ms)
  Test the status paths
    ✓ The GET / route should give status code 200 (28ms)
    ✓ The GET /status route should give status code 200 (7ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        1.179s
Ran all test suites.

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  TCPSERVERWRAP

      27 |     test('The GET /status route should give status code 200', async () => {
      28 |         expect.assertions(1);
    > 29 |         const response = await request(app).get('/status');
         |                                             ^
      30 |         expect(response.statusCode).toBe(200);
      31 |     });
      32 | });

      at Test.Object.<anonymous>.Test.serverAddress (node_modules/supertest/lib/test.js:59:33)
      at new Test (node_modules/supertest/lib/test.js:36:12)
      at Object.obj.(anonymous function) [as get] (node_modules/supertest/index.js:25:14)
      at Object.get (tests/app.test.js:29:45)

^C
tksilicon commented 5 years ago

For me this did the trick

afterAll(async () => {
  await new Promise(resolve => setTimeout(() => resolve(), 500)); // avoid jest open handle error
});

Seems like it needs some more ticks to close that handle.

This nice. Solve the issue for me. Thanks.

Baystef commented 4 years ago

My issue was actually being caused by express-session middleware. I suspect something abnormal was happening with supertest requests, quick workaround was to include this in any tests using supertest

jest.mock('express-session', () =>
  (options: SessionOptions) =>
    (req: Request, res: Response, next: NextFunction) => {
      next();
});

Can you please elaborate on how you did this? I don't understand how the SessionOptions was passed into the function, it keeps throwing errors, a more detailed snippet would do, Thanks. I have a strong feeling that the problem is from express session. @cif

elucidsoft commented 4 years ago

I literally just wasted 4 hours on this, had to use several of the solutions mentioned here. What FINALLY worked for me after literally trying every single one of them was a combination of @tksilicon solution + @lukaswilkeer + @carlafranca

To summarize I use the timeout in the afterAll, and I pass in --forceExit --detectOpenHandles --maxWorkers=1 and it finally worked.

I tried each of these on their own, but still had issues. The port mapping solution that so many had luck with did absolutely nothing for me either.

johncmunson commented 4 years ago

@rimiti this is by far the most requested feature (bugfix really), especially when considering the activity on these two issues which have the same root cause. https://github.com/visionmedia/supertest/issues/437 https://github.com/visionmedia/supertest/issues/436

If you are unable to provide the solution anytime in the near future, would you be able to give some guidance on where to start in the codebase so someone from the community is more likely to pick this up?

Or do you think this might be an issue with Jest and not supertest?

jlei523 commented 4 years ago

@cif The issue is not usually caused by express-session itself, but rather by the particular store used. I usually rely on the default MemoryStore on tests, if it is really hard to properly shutdown the upstream connection to the store.

I'm using express-session and redis store. Can you share your solution if you have one?

Nothing in this thread has worked for me.

jlei523 commented 4 years ago

Weirdly, if I run the whole suite, Jest exists correctly.

garyo commented 4 years ago

I'm also seeing the same thing -- simple server test, TCPSERVERWRAP handle stays open:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  TCPSERVERWRAP

      24 |   test('should get an example by id', () =>
      25 |     request(Server)
    > 26 |       .get('/api/v1/examples/2')
         |        ^
      27 |       .expect('Content-Type', /json/)
      28 |       .then(r => {
      29 |         expect(r.body).toBeInstanceOf(Object)

      at Test.Object.<anonymous>.Test.serverAddress (../../node_modules/supertest/lib/test.js:59:33)
      at new Test (../../node_modules/supertest/lib/test.js:36:12)
      at Object.obj.(anonymous function) [as get] (../../node_modules/supertest/index.js:25:14)
      at Object.test (test/examples.controller.spec.ts:26:8)

I tried adding the afterAll timeout suggested above, but that doesn't fix it. I'm using .then rather than await; should be the same, right? (@elucidsoft 's idea of --forceExit --detectOpenHandles along with the afterAll timeout does "fix" it, I don't see the error and it does exit, but I expect the root cause is still there.)

Running jest 24.9.0, supertest 4.0.2, express 4.17.1, Linux Ubuntu 18.04.

katlimruiz commented 4 years ago

in my case I was opening a REDIS client, and indeed when I did not have rc.quit(), it was kept open. I added rc.quit() and jest ended gracefully.

nfroidure commented 4 years ago

Imo, it is not a Jest issue. There is a way to add some extra logic to close sockets at server close by maintaining a ref of available sockets for dev (the default behavior is good for production and graceful reload):

GrayStrider commented 4 years ago

@AlexisNava

Try this in your app.test

const request = require('supertest');
const app = require('../app');
describe('App Request', () => {
  test('should responds with 404', async (done) => {
    const result = await request(app).get('/');
    expect(result.status).toBe(404);
    done();
  });
});

did the trick for me, but linter complains not to use callbacks. I know it's not SO and perhaps the question is more about Jest itself, but still, could someone add some clarity to that behaviour and why above solution is required?

GrayStrider commented 4 years ago
afterAll(async () => {
    await sleep(500)
})

works too.

parthnaik commented 4 years ago

I am facing this same issue. The strange part is that if I am using both flags --detectOpenHandles --forceExit, if I run it locally, there are no warnings but when running it via CircleCI, it gives me a warning saying it detected a potentially open handle. However, using the above flags does result in the tests passing so it's a non-issue for now other than the annoying warning on my console.

dotku commented 4 years ago

@AlexisNava

Try this in your app.test

const request = require('supertest');
const app = require('../app');
describe('App Request', () => {
  test('should responds with 404', async (done) => {
    const result = await request(app).get('/');
    expect(result.status).toBe(404);
    done();
  });
});

but the test never exist :(

dotku commented 4 years ago

@AlexisNava

Try this in your app.test

const request = require('supertest');
const app = require('../app');
describe('App Request', () => {
  test('should responds with 404', async (done) => {
    const result = await request(app).get('/');
    expect(result.status).toBe(404);
    done();
  });
});

According what I know, await should not work work with done

iamjoross commented 4 years ago

got it working with just jest/supertest/mongoose (removing mockgoose). Thanks for the help.

let server;

beforeAll(async (done) => {
  await mongoose.connect('mongodb://localhost:27017/testdb');
  server = app.listen(4000, () => {
    global.agent = request.agent(server);
    done();
  });
});

afterAll(async () => {
  await server.close();
  await mongoose.disconnect();
});

Now time to figure out the issue with mockgoose joy

This solves my issue.

shijiezhou1 commented 4 years ago

describe('AppController (e2e)', () => { let app: INestApplication;

beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile();

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

});

it('/ (GET)', () => { return request(app.getHttpServer()) .get('/') .expect(200) .expect('Hello World!'); });

it('/weather (GET)', () => { return request(app.getHttpServer()) .get('/weather') .expect(200) .expect('weather'); })

afterEach( async () => { await app.close() }); });

The key for that is to add

afterEach( async () => {
    await app.close()
});
nikhilwairagade commented 4 years ago

how to do this with firestore based application

joticajulian commented 4 years ago

It can be simplified to

afterAll(async () => {
  await new Promise(resolve => setTimeout(resolve, 500));
});
soultoru commented 4 years ago

I found simple open handle keeps case and that solution.

Open handle keeps case test code

const request = require('supertest')

const app = (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' })
  res.end('okay')
}

test('async await', async () => {
  const res = await request(app).get('/')
  expect(res.status).toBe(200)
})

Open handle keeps result

 PASS  test/failure.test.js
  ✓ async await (106ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.041s
Ran all test suites matching /failure/i.

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  TCPSERVERWRAP

       9 | 
      10 | test('async await', async () => {
    > 11 |   const res = await request(app).get('/')
         |                                  ^
      12 |   expect(res.status).toBe(200)
      13 | })
      14 | 

      at Test.serverAddress (node_modules/supertest/lib/test.js:59:33)
      at new Test (node_modules/supertest/lib/test.js:36:12)
      at Object.get (node_modules/supertest/index.js:25:14)
      at Object.test (test/failure.test.js:11:34)

Done in 2.58s.

Success case test code

const request = require('supertest')

const app = (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' })
  res.end('okay')
}

test('async await with done', async (done) => { // use callback
  const res = await request(app).get('/')
  expect(res.status).toBe(200)
  done() // exec callback after expect
})

Success result

 PASS  test/success.test.js
  ✓ async await with done (111ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.869s
Ran all test suites matching /success/i.
Done in 2.14s.

I think this case is Jest probrem. Because it's not mentioned in the manual.

soultoru commented 4 years ago

This is already commented by @alfonsoal1983.

RaneWallin commented 4 years ago

Passing done to the test and invoking it at the end resolved this for me, as mentioned by @soultoru above.

  test("returns a title of a game when passed a valid product id", async (done) => {
    await request(app).get("/description/title/1").expect(200);
    done();
  });
marciobera commented 4 years ago

It worked for me just passing the callback done at the end(done) of the last test, like that:

        it('title...', done => {
            return request(app.getHttpServer())
                ...
                .end(done);
        });
katlimruiz commented 4 years ago

Finally this worked for me, hope this helps to others. I've been banging my head for hours, even the simplest tests with supertests were always kept hanging.

        const srv = app.listen();
        const request = supertest(srv);
        request.get('/get')
            .expect(200)
            .end(res => {
                // expect(res.body).toBe('done');
                done();
                srv.close();
            });

And by the way, how did I find it? by using https://www.npmjs.com/package/leaked-handles.

chrisvoo commented 4 years ago

This is my working example, just in case it may help:

import request from 'supertest';
import * as dotenv from 'dotenv';
// this is a private package which exports also a mongoose reference. The connection to the db is done elsewhere.
import { mongoose } from '@sostariffe/bootstrappers';
import bootstrap, { BootstrapResponse } from '../src/libs/bootstrap';

let bootType: BootstrapResponse;

beforeAll(async () => {
  dotenv.config();
  bootType = await bootstrap();
});

afterAll((done) => {
  bootType.server.close((err) => {
    if (err) {
      console.error(err);
    }
    mongoose.connection.close((errMongo: Error) => {
      if (errMongo) {
        console.error(err);
      }

      done();
    });
  });
});

it('Verify route', (done) => {
  request(bootType.app)
    .post(`${process.env.APP_BASE_PATH}/verify`)
    .set('Accept', 'application/json')
    .send({ param: ['hey'] })
    .expect(200)
    .then((response) => {
      expect(response.body).not.toBeNull();
      done();
    });
});

where bootstrap function is defined as the following:

import express, { Request, Response, NextFunction } from 'express';
import { Server } from 'http';
import { bootstrapMongoose } from '@sostariffe/bootstrappers';
import blacklist from '../routes/blacklist';
import verify from '../routes/verify';

export type BootstrapResponse = {
  server: Server,
  app: express.Express,
}

/* This function boots a listening express instance and mongoose (hidden by a private function) */
export default async function bootstrap(): Promise<BootstrapResponse> {
  const bootstrapExpress = new Promise<BootstrapResponse>((resolve, reject) => {
    const app = express();
    const port = process.env.PORT;

    app.disable('x-powered-by');
    app.use(express.urlencoded({ extended: false }));
    app.use(express.json());

    app.use(`${process.env.APP_BASE_PATH}/blacklist`, blacklist);
    app.use(`${process.env.APP_BASE_PATH}/verify`, verify);

    app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
      console.error(err.stack);
      const statusCode = res.statusCode || 500;
      res.status(statusCode).json({
        error: true,
        description: err.message,
      });
    });

    const server = app.listen(port, () => {
      console.log(`Server listening at http://localhost:${port}`);
      resolve({
        app,
        server,
      });
    });
  });

  const [bootstrapResponse] = await Promise.all([
    bootstrapExpress,
    bootstrapMongoose(),
  ]);

  return bootstrapResponse;
}
PawFV commented 4 years ago

Here is my solution.

index.js

import env from 'dotenv'
import express from 'express'
const app: any = express()
const PORT = process.env.PORT || 4000
import middlewares from '../../middleware/common'
import Logger, { logServerStatus } from '../../log/Logger'

env.config({ path: '.env' })
Logger()
middlewares.forEach((mdlware) => app.use(mdlware))

// HTTP SERVER
// SAVE THE EXPRESS CONNECTION IN A CONST
const server = app.listen(PORT, () => logServerStatus(PORT))

// EXPORT EXPRESS APP & SERVER CONNECTION
export default server
export {app}

test.js

import dbHandler from './dbConnection'
import server,{app} from './server/index'
import supertest from 'supertest'

const request = supertest(app) // PASS THE EXPRESS APP

beforeAll(async () => {
  await dbHandler.connect()
})

afterAll(async (done) => {
  await dbHandler.disconnect()
  await server.close() // CLOSE THE SERVER CONNECTION
  await new Promise(resolve => setTimeout(() => resolve(), 500)); // PLUS THE HACK PROVIDED BY @yss14
  done()
})
andrescabana86 commented 3 years ago

Hello there, in my case I have the same problem and jest --detectLeaks --detectOpenHandles shows nothing

Screen Shot 2020-11-07 at 16 28 51

this is the repo https://github.com/andrescabana86/epic-react-boilerplate

only one test, no services, nothing should be keeping Jest from the exit but still happening

lukaswilkeer commented 3 years ago

I've tested with node v14.04 and v12.18.

On both works, but on node v12 shows a warning about Node Target Mapping (ts-jest config). On the other hand, you could try --forceExit.

Em sáb., 7 de nov. de 2020 às 16:30, Andres Cabana notifications@github.com escreveu:

Hello there, in my case I have the same problem and jest --detectLeaks --detectOpenHandles shows nothing

[image: Screen Shot 2020-11-07 at 16 28 51] https://user-images.githubusercontent.com/1840542/98449873-70c6b580-2116-11eb-9f9b-52e2a53a164b.png

this is the repo https://github.com/andrescabana86/epic-react-boilerplate

only one test, no services, nothing should be keeping Jest from the exit but still happening

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/visionmedia/supertest/issues/520#issuecomment-723485071, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANZZXDWLENVKN2I5BNWXJLSOWN67ANCNFSM4GBUADRQ .

-- Lukas Wilkeer Desenvolvedor, empreendedor e aventureiro. +55 031 9413-8900

cafeepixel.com.br http://cafeepixel.com.brFaça parte do GDG. http://gdgbh.org

danday74 commented 3 years ago

This worked well for me ...


  import request from 'supertest'
  import app from '../../server'

  let server: Server
  let agent: request.SuperAgentTest

  beforeEach((done) => {
    server = app.listen(4000, () => {
      agent = request.agent(server)
      done()
    })
  })

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

However, I had to make the following changes to my server file:

if (process.env.NODE_ENV !== 'test') {
  app.listen(appConfig.port, () => {
    console.log(`Server running on port ${appConfig.port}`)
  })
}

export default app

The above change means that the server still starts when you run npm start but does not start the normal server when you are testing.

My npm start command from package.json is:

"scripts": {
  "test": "cross-env NODE_ENV=test jest --detectOpenHandles",
}
alexey2baranov commented 3 years ago

I have found the reason and the solution for me. It was because I had readonly folder inside project, that was created by Docker volume. After removing this folder this error have gone away.

igorvolnyi commented 3 years ago

This is my case. I tested REST API endpoints as shown in example at Testing | NestJS.

The problem code is

it(`/GET cats`, () => {
    // This causes the problem.
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
});

And the solution is to use await instead of return:

it(`/GET cats`, () => {
    await request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });
ZaidRehman commented 3 years ago

None of the above mentioned worked for me but somehow below code worked

jest.config.js

module.exports = {
    ....
    globalTeardown: 'test-teardown-globals.js',
}

test-teardown-globals.js

module.exports =  () => {
    process.exit(0)
};
DanJFletcher commented 3 years ago

This article helped me find a clean solution. I got it working by manually configuring the agent as mentioned here https://github.com/visionmedia/supertest/issues/520#issuecomment-436071071

However I couldn't figure out how to make this setup and teardown reusable so after reading this article: https://rahmanfadhil.com/test-express-with-supertest/ I realised I can just export a helper function that creates a new app and use it like:

const request = require('supertest')
const { createServer } = require('./index')

const app = createServer()

it('can get a token given valid auth credentials', async () => {
    const res = await request(app)
        .post('/login')
        .send({
            username: 'tester',
            password: 'password'
        })

    expect(res.statusCode).toEqual(200)
    expect(res.body).toHaveProperty('token')
})
AugustoAmaral commented 3 years ago

I was having an issue with this case because I was using Sequelize and a test database to run queries but the database keeps open after request.

My solution was:

const sequelizeDatabase = require("../../src/config/sequelizeDatabase");

afterAll(() => {
  sequelizeDatabase.close();
});
fuciktomas commented 3 years ago

@jonathansamines you mean passing the done like in your example?

let server;

beforeEach((done) => {
    server = app.listen(4000, (err) => {
      if (err) return done(err);
       global.agent = request.agent(server);
       done();
    });
});

afterEach((done) => {
  return  server && server.close(done);
});

this is not solving it either

done helps me :)

Orlayhemmy commented 3 years ago

I added this condition around app.listen process.env.NODE_ENV !== 'test'. Works like charm

if (process.env.NODE_ENV !== 'test') {
    app.listen(port, ....)
}
parasVohra commented 3 years ago

I solved this issue simply passing my app hosting URL to request as an argument like


const request = require("supertest");

describe("Index file Tests", () => {
  it("should handle get request for /api/ping", async (done) => {
    const response = await request("http://localhost:2021").get("/api/ping");
    expect(response.status).toBe(200);
    expect(response.body).toEqual({ success: true });
    done();
  });
}); 
nfantone commented 3 years ago

Three years later and I still can't get this to work. The most basic setup isn't going for me: no databases, no extraneous middleware, no other resources.

const express = require('express')
const request = require('supertest')

test('should not leak memory', async () => {
  const app = express()
  await request(app).get('/')
})
❯ jest --detectOpenHandles --detectLeaks
 FAIL  src/memory-leak.test.js
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

I've tried any and all combinations of .end(done), async usages and manual server/agent closing mentioned in this thread and nothing worked for me. Did anyone managed to get this running without leaking? Maybe even a false positive from jest?

tperrinweembi commented 3 years ago

I'd chased this down, just to find out that it was a simple forgetfulness on my part. Our application fell back on the database that wasn't set up on CI or stubbed, causing a long wait that manifested in TCPSERVERWRAP.

tl;dr Check your application for other reasons that your request could hang

Hi sbonami, could you please tell us more on how to check that "the db is set up on CI or stubbed"; I don't know what does that mean.

agalatan commented 3 years ago
paulgrieselhuber commented 3 years ago

None of the above mentioned worked for me but somehow below code worked

jest.config.js

module.exports = {
    ....
    globalTeardown: 'test-teardown-globals.js',
}

test-teardown-globals.js

module.exports =  () => {
    process.exit(0)
};

This was the solution for me.

damienbry commented 2 years ago

Thanks @paulisloud, it did the trick 👍

JohanAltamar commented 2 years ago

module.exports = () => { process.exit(0) };

This solved the problem when I run jest --runInBand --detectOpenHandles but when runing normally the warning is still there. Any suggestions?

raulfdm commented 2 years ago

For people who're testing Strapi + supertest, I've realized that to prevent this log, I need to destroy all connections on afterAll:

// <rootDir>/tests/app.test.js

afterAll(async () => {
  const dbSettings = strapi.config.get('database.connections.default.settings');

  //This will delete test database after all tests
  if (dbSettings && dbSettings.filename) {
    const tmpDbFile = `${__dirname}/../${dbSettings.filename}`;
    if (fs.existsSync(tmpDbFile)) {
      fs.unlinkSync(tmpDbFile);
    }
  }

  await strapi.connections.default.context.destroy(); // <- THIS DOES THE TRICK
})
klh commented 2 years ago

give your app a recognisable name by setting process.title so if you're running a Koa server from a node script as part of you JEST setup you can

process.title="MyServer

you could start it from either cli, npm or jest-global-setup.js

then in jest-global-teardown.js you just invoke

killProcess("MyServer)

you could for instance use : https://www.npmjs.com/package/kill-process-by-name

see: https://jestjs.io/docs/configuration#globalteardown-string

mishalalex commented 2 years ago

jest - ^27.2.5, node - v16.11.1, npm = 8.0.0

Resolving the timeouts in the afterAll() section helped me as well. But here is something unusual that I have found = if there is a function declaration in the old format (i.e. function funcation_name() {}), then I used to get this error with TLSWRAP. How I solved it is by converting all such functions into arrow functions. I hope this helps someone if it is not already covered.

koderka2020 commented 2 years ago

For me this did the trick

afterAll(async () => {
    await new Promise(resolve => setTimeout(() => resolve(), 500)); // avoid jest open handle error
});

Seems like it needs some more ticks to close that handle.

@yss14 Thanks for your help, It solved the issue for me too, which I was chasing for couple of days but can you elaborate why this resolve the issues?

Hi! may I ask you where did you pass that piece of code? within describe()? Or outside of that? I saw many articles that say just place the afterAll() on top of your code but that doesn't do the trick for me. and actually placing it within the file neither =/

craigmiller160 commented 2 years ago

Howdy everyone. Figured I would chime in. I was running into this issue and it was driving me absolutely mad. I have discovered something that may be of use to folks here.

First, I discovered a connection between errors in Express itself and this behavior where it wouldn't shut down. My specific problem is a transitive dependency clash leading to a "called on undefined" error, but that specific detail is immaterial to this. My point is, Express itself was blowing up when trying to process a request.

I can prove this in my application because the same test I was having this "won't shut down" bug on, if I run the app and call it with postman, fails with that same "called on undefined" error. Most importantly, Express itself completely crashes when this happens.

Anyway, I added the following to my application:

process.on('uncaughtException', (err) => {
    console.log('UncaughtException', err);
});

This is to catch and gracefully log any exceptions like this. As soon as I had this in place, all of my "express won't shut down" errors went away. I can run my test, it fails (due to the aforementioned "called on undefined" bug that I still haven't gotten around to fixing because I've been stuck on this express shutting down issue), but then the test suite gracefully shut down.

I am using this solution alone, without applying any of the other hack-y fixes in this thread. I'm hoping maybe this helps someone else who is struggling with this.

PS. One more thing: always use timeout() on your supertest tests. I noticed one more thing, where the individual test may hang for a long time on a problem, and so long as I have that timeout in place it'll close gracefully.

raarts commented 2 years ago

@craigmiller160 Can you explain your comment on timeout() use? Jest has its own timeout, do these interrelate?

DercilioFontes commented 2 years ago

For me, it was solved with a condition for adding the listener to the app if not 'test'. Jest run as NODE_ENV=test

if (process.env.NODE_ENV !== 'test') {
        app.listen(port, (): void => {
            console.log(`Server running on port ${port}`);
        });
    }

And for avoiding this warning (https://github.com/lorenwest/node-config/wiki/Strict-Mode), I added a config json file with "env": "test",.

bhavin-a commented 2 years ago

Hi @niftylettuce , is there any workaround for this? None of the above solutions seem to work and this is coming in very simple individual tests as well. Can't use custom ports for 100+ tests as sometimes, they collide and the tests fail. Does anyone else have any solution? Even a slight help is appreciated. Much Thanks!