CodePark/ questions / Testing Nest apps
START PRACTICINGPRACTICE
Backend question · NestJS › Testing Nest apps

How do you write an end-to-end test for a Nest HTTP endpoint?

let app: INestApplication;

beforeAll(async () => {
  const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
    .overrideProvider(MailService).useValue({ send: jest.fn() })
    .compile();
  app = moduleRef.createNestApplication();
  app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
  await app.init();
});

afterAll(() => app.close());

it("GET /cats", () => request(app.getHttpServer()).get("/cats").expect(200));

Start the real app inside a testing module, then send HTTP requests to it with Supertest.

The steps:

  • Compile a testing module that imports the real AppModule.
  • Optionally, replace external services like mail or payment providers with overrideProvider().useValue().
  • Call createNestApplication() and await app.init(). You get a full app with all middleware, guards, pipes and filters connected.
  • Use Supertest to send real HTTP requests to app.getHttpServer(). Check the status and the body.
  • Close the app in afterAll. Otherwise open connections keep Jest running.

A common problem: global setup in main.ts is not applied here, because the test doesn't run main.ts. Examples are useGlobalPipes and setGlobalPrefix. Fix it in one of these ways:

  • Repeat the setup in the test.
  • Move it into a shared function that both use.
  • Register it as APP_* providers, such as APP_PIPE.
  • Import the real AppModule into a testing module.
  • Call createNestApplication() and then app.init().
  • Send requests with Supertest to app.getHttpServer().
  • Override external services, and close the app after the tests.
  • Global setup in main.ts is not applied automatically.