jest timeout on express server using supertest

I’m trying to test an express app’s endpoints using jest and supertest. Here are my files:

// backend/tests/integration.test.ts
const server = require('../server');
const supertest = require('supertest');
const appTest = supertest(server);

describe('Integration tests', () => {
  it('GET /api/ping', async () => {
    const expected = { status: 200, body: { success: true } }
    const res = await appTest.get('/api/ping');
    expect(res.status).toEqual(expected.status);
    expect(res.body).toEqual(expected.body);
  });
});
// backend/server.ts
import app from './src/app';

const PORT = 3000;

const server = app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

export default server;
// backend/src/app.ts
const express = require('express');
const app = express();

app.get('/api/ping', (req, res) => {
  res.status(200).json({
    'success': true
  });
});

export default app;

I keep getting the error:

TypeError: app.address is not a function

And the stack trace says that the error is on the line:

       8 |   it('GET /api/ping', async () => {
       9 |     const expected = { status: 200, body: { success: true } }
    > 10 |     const res = await appTest.get('/api/ping');
         |                               ^
      11 |     expect(res.status).toEqual(expected.status);
      12 |     expect(res.body).toEqual(expected.body);
      13 |   });

My config looks like:

// package.json
...
"scripts": {
  "test": "jest"
}
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  modulePathIgnorePatterns: ["<rootDir>/dist/"],
  transform: {
    '^.+/*.(ts|tsx)?$': 'ts-jest'
  }
};
// babel.config.js
module.exports = {
  presets: ['@babel/preset-env']
};
// tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist"
  },
  "lib": ["es2015"],
  "exclude": [
    "../node_modules"
  ],
  "include": [
    "./**/*.ts"
  ]
}

I don’t know why this is happening. Have tried googling & reading about the timeout error on stack overflow but to no avail.

Answer

at backend/tests/integration.test.ts just use the server without http.createServer

changes should be made :

  1. instead const appTest = supertest(http.createServer(server)); use const appTest = supertest(server);
  2. remove done from signature you don’t need it if you using async-await , change test signature to it('GET /api/ping', async () => {...}
  3. remove the done call at the end of the spec
  4. add to jest.config allowJs: true,
  5. compare versions of dependicies

package.json

{
  "name": "node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "babel": "^6.23.0",
    "express": "^4.17.1",
    "jest": "^27.2.0",
    "supertest": "^6.1.6",
    "ts-jest": "^27.0.5"
  },
  "devDependencies": {
    "@types/jest": "^27.0.1"
  }
}