NestJS createTestingМодуль и ошибка getHttpServer() 503

#unit-testing #nestjs #e2e-testing

Вопрос:

Я использую NestJS 7.6.0, и у меня возникли проблемы с тестированием E2E.

У меня есть очень простой модуль, который предоставляет маршрут /работоспособности в своем контроллере. Я хотел бы протестировать этот маршрут, используя функцию тестирования E2E NestJS, описанную здесь:

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

В настоящее время я использую тот же самый код:

 
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)
    });
});

 

Если я выполню этот тест с npm run test этой ошибкой, у меня будет эта ошибка:

 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 | });

 

Похоже, что HTTPServer не запущен.

Чтобы это сработало, я должен изменить код следующим образом:

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

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

Я просто добавил app.listen(3000) «а», и тест прошел. Я не знаю, является ли это упущением в документации или я сделал это неправильно.

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 {}

 

Как вы можете видеть, я импортирую TerminusМодуль и объявляю свои 2 контроллера: AppController и HealthController.

В AppController у меня есть только маршрут /ping с надписью «привет, мир».

 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();
  }
}

 

И в HealthController у меня есть только маршрут /health, который вызывает /ping на локальном хосте.

 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'),
    ]);
  }
}

 

И если вы запустите тесты с npm run test , он покажет ошибку 503, связанную выше. Чтобы это сработало, мне нужно добавить await app.listen(3000); метод beforeAll() сразу после инициализации() (см. Выше).

Я думаю, что моя проблема связана с «терминалом», потому что, если я начну новый проект NestJS, в котором не используется терминал, тестирование e2e работает нормально, без необходимости добавлять .listen().

Нужно ли мне делать что-то особенное в createTestingModule() с помощью TerminusModule?

Спасибо

Комментарии:

1. Пожалуйста, поделитесь содержимым конечной точки работоспособности. Вам не нужно добавлять прослушиватель HTTP, чтобы запустить этот тест