import { HttpServer, INestApplication, INestMicroservice, Logger, } from '@nestjs/common'; import { MicroserviceOptions } from '@nestjs/common/interfaces/microservices/microservice-configuration.interface'; import { NestMicroserviceOptions } from '@nestjs/common/interfaces/microservices/nest-microservice-options.interface'; import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface'; import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface'; import { Type } from '@nestjs/common/interfaces/type.interface'; import { loadPackage } from '@nestjs/common/utils/load-package.util'; import { NestApplication, NestApplicationContext } from '@nestjs/core'; import { ApplicationConfig } from '@nestjs/core/application-config'; import { NestContainer } from '@nestjs/core/injector/container'; import { Module } from '@nestjs/core/injector/module'; export class TestingModule extends NestApplicationContext { constructor( container: NestContainer, scope: Type[], contextModule: Module, private readonly applicationConfig: ApplicationConfig, ) { super(container, scope, contextModule); } public createNestApplication( httpAdapter?: HttpServer, options?: NestApplicationOptions, ): T { httpAdapter = httpAdapter || this.createHttpAdapter(); this.applyLogger(options); this.container.setHttpAdapter(httpAdapter); const instance = new NestApplication( this.container, httpAdapter, this.applicationConfig, options, ); return this.createAdapterProxy(instance, httpAdapter); } public createNestMicroservice( options: NestMicroserviceOptions & MicroserviceOptions, ): INestMicroservice { const { NestMicroservice } = loadPackage( '@nestjs/microservices', 'TestingModule', () => require('@nestjs/microservices'), ); this.applyLogger(options); return new NestMicroservice( this.container, options, this.applicationConfig, ); } private createHttpAdapter(httpServer?: T): HttpServer { const { ExpressAdapter } = loadPackage( '@nestjs/platform-express', 'NestFactory', () => require('@nestjs/platform-express'), ); return new ExpressAdapter(httpServer); } private applyLogger(options: NestApplicationContextOptions | undefined) { if (!options || !options.logger) { return; } Logger.overrideLogger(options.logger); } private createAdapterProxy(app: NestApplication, adapter: HttpServer): T { return (new Proxy(app, { get: (receiver: Record, prop: string) => { if (!(prop in receiver) && prop in adapter) { return adapter[prop]; } return receiver[prop]; }, }) as any) as T; } }