0

App.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        SOME_ENV_VARIABLE: Joi.string().required(),
      }),
      isGlobal: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

app.e2e-spec.ts:

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';

describe('AppController (e2e)', () => {
  let app: INestApplication;

  beforeEach(async () => {
    process.env.SOME_ENV_VARIABLE = 'kuku';
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

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

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

If I run this test regularly the test fails:

 npm run test:e2e

with the following error: Config validation error: "SOME_ENV_VARIABLE" is required

But if I run the test with env

export SOME_ENV_VARIABLE=kuku && npm run test:e2e

the test passes

I don't understand why

process.env.SOME_ENV_VARIABLE = 'kuku';

If I run the test without the validationSchema it works fine in both cases

Rami Loiferman
  • 853
  • 1
  • 6
  • 22
  • 1
    It may happen because nest is running validation before you manually set this variable in the code. Try to set some breakpoints in the code and verify the behaviour with the debugger. I do not have time to check my hypothesis now, but I think that because `ConfigModule` is global, validation will run at the moment when you are importing `AppModule` into the test file – Moti Aug 22 '22 at 10:03
  • You totally right, the validate method is running at the "import" time and because of that it will run only once for the entire test file – Rami Loiferman Aug 24 '22 at 19:00

1 Answers1

0

As @moti mentioned the validate method is running at the Import time. So the only way to test it against multiple different scenarios is to require it on the fly during the test:

Instead of:

import { AppModule } from "../src/app.module";

Do:

 beforeEach(() => {
    process.env.SOME_ENV_VARIABLE = 'kuku';
    jest.resetAllMocks();
    jest.requireActual("../src/app.module");
});

This way it will run with the overridden environment variable

Rami Loiferman
  • 853
  • 1
  • 6
  • 22