NestJS createTestingModule and getHttpServer() error 503

Viewed 1010

I'm using NestJS 7.6.0 and I'm experiencing a problem with E2E testing.

I have a very simple module that exposes a /health route in its controller. I'd like to test this route using the E2E testing feature of nestJs documented here:

https://docs.nestjs.com/fundamentals/testing#end-to-end-testing

I'm currently using the quite same code:


describe('AppController (e2e)', () => {

    let app: INestApplication;
    beforeAll(async () => {
        const moduleFixture: TestingModule = await Test.createTestingModule({     
            imports: [AppModule]
        }).compile();

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

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

If I run this test with npm run test I have this error:

npm run test

> dv-ewok-api@0.0.1 test ....
> jest

[Nest] 54638   - 28/06/2021, 14:53:30   [ExceptionHandler] Health Check has failed! {"ready":{"status":"down","message":"connect ECONNREFUSED 127.0.0.1:3000"}}
 FAIL  src/health/health.controller.spec.ts
  ● AppController (e2e) › /health (GET)

    expected 200 "OK", got 503 "Service Unavailable"

  32 |         return await request(app.getHttpServer())
  33 |             .get('/health')
> 34 |             .expect(200)
     |              ^
  35 |
  36 |     });
  37 | });

It seems that the httpServer is not running.

To make it work I have to modify the code like this:

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

        app = moduleFixture.createNestApplication();
        await app.init();
        await app.listen(3000); // <===== ADD THIS LINE
    }); 
...

I just added a app.listen(3000) and the test passed. I don't know if this is an oversight in the documentation or if I did it wrong.

Thank you for your help.

Edit for adding some more details

For the HealthCheck part, I'am using the NestJS Terminus integration described here.

So, my app.module looks like this :

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { HealthController } from './health/health.controller';

@Module({
  imports: [TerminusModule],
  controllers: [AppController, HealthController],
  providers: [AppService],
})
export class AppModule {}

As you can see, I import the TerminusModule and I declare my 2 controllers: AppController and HealthController.

In AppController I have just a /ping route that says "hello world"

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('/ping')
  getHello(): string {
    return this.appService.getHello();
  }
}

And in HealthController I have just the /health route that calls the /ping on localhost.

import { Controller, Get } from "@nestjs/common";
import { HealthCheck, HealthCheckService, HttpHealthIndicator } from "@nestjs/terminus";

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('ping', 'http://localhost:3000/ping'),
    ]);
  }
}

And if you run tests with npm run test, it shows the 503 error linked above. To make it work, I need to add await app.listen(3000); in the beforeAll() method right after the init() (cf. above).

I think my problem comes from "terminus" because if I start a new NestJS project which does not use Terminus, e2e testing works fine, without the need to add the .listen().

Do I need to do something special in the createTestingModule() with TerminusModule?

Thank you

0 Answers
Related