typescriptjestjssupertestfastify

"Cannot read properties of undefined" in hooks and open TCP handle after test


I'm working on a Fastify project using Jest and Supertest for end-to-end tests. However, I'm encountering a couple of issues:

Here’s my basic test setup:

Test (server.e2e.test.ts):

import supertest from 'supertest';
import buildServer from '../server';

describe('Server', () => {
  let app: Awaited<ReturnType<typeof buildServer>>;

  beforeAll(async () => {
    app = await buildServer();
  });

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

  test('GET /api/auth/healthcheck', async () => {
    await supertest(app.server).get('/api/auth/healthcheck').expect(200);
  });
});

Fastify Server (server.ts):

import Fastify from 'fastify';
import sensiblePlugin from '@fastify/sensible';
import cookiePlugin from '@fastify/cookie';
import csrfPlugin from '@fastify/csrf-protection';
import helmetPlugin from '@fastify/helmet';
import authRoutes from './routes';

const buildServer = async () => {
  const fastify = Fastify({ logger: true });

  await fastify.register(sensiblePlugin);
  await fastify.register(cookiePlugin);
  await fastify.register(csrfPlugin);
  await fastify.register(helmetPlugin);
  await fastify.register(authRoutes, { prefix: '/api/auth' });

  return fastify;
};

export default buildServer;

Error 1:

TypeError: Cannot read properties of undefined (reading 'length')

      at next (../../node_modules/.pnpm/fastify@5.0.0/node_modules/fastify/lib/hooks.js:334:32)
      at preParsingHookRunner (../../node_modules/.pnpm/fastify@5.0.0/node_modules/fastify/lib/hooks.js:364:3)
      at runPreParsing (../../node_modules/.pnpm/fastify@5.0.0/node_modules/fastify/lib/route.js:568:5)
      at Object.routeHandler [as handler] (../../node_modules/.pnpm/fastify@5.0.0/node_modules/fastify/lib/route.js:490:7)
      at Router.callHandler (../../node_modules/.pnpm/find-my-way@9.0.1/node_modules/find-my-way/index.js:552:14)
      at Router.lookup (../../node_modules/.pnpm/find-my-way@9.0.1/node_modules/find-my-way/index.js:530:17)
      at Server.preRouting (../../node_modules/.pnpm/fastify@5.0.0/node_modules/fastify/fastify.js:886:14)

Error 2:

thrown: "Exceeded timeout of 5000 ms for a test.
    Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

      13 |   });
      14 |
    > 15 |   test('GET /api/auth/healthcheck', async () => {
         |   ^
      16 |     await supertest(app.server).get('/api/auth/healthcheck').expect(200);
      17 |   });
      18 | });

      at src/__tests__/server.e2e.test.ts:15:3
      at Object.<anonymous> (src/__tests__/server.e2e.test.ts:4:1)

Solution

  • What about await app.listen({ port: port }); after build?

    You can add

      afterAll(async () => {
        app.close();
      }, 4000);
    

    So it's abort without waiting for the promise to resolve if exceeding this time.