Im writing an e2e test for my api. To implement e2e test i have to use AppModule in imports when creating TestingModule:
beforeAll(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
})
// ...
The problem is that AppModule has import TypeOrmModule.forRootAsync({useFactory: getTypeOrmConfig, dataSourceFactory: getDataSource, })
, where getTypeOrmConfig
gets config from variable environment. But in test i am mocking services and i dont need to have db connection.
Im looking for a way to override this module with another configuration, that is for e2e tests only.
Change variables in .env doesnt fits, because integration tests are working with live database, and i dont want to download different .env
in my CI for running different kinds of tests.
I have tried overrideModule
:
beforeAll(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
})
.overrideModule(
TypeOrmModule.forRoot({}), || TypeOrmModule || TypeOrmModule.forRootAsync({})
)
.useModule(
TypeOrmModule.forRoot({
type: "sqlite",
database: "./test/database-mock/db",
}),
)
//...
But it doesnt work - app still tries to connect to the live database.
Is there a way to override imported module in AppModule while creating TestModule? We can override providers in imported modules inside AppModule, im looking for method to do this but with imported module.
While configuring TypeOrmModule
, I intentionally use process.env
instead of the configService
to get my environment variables.
TypeOrmModule.forRootAsync({
useFactory: () => {
//N.B: I use process.env here instead of configService.get
// because of e2e tests. process.env can be mutated and updated
// with connection details for a testcontainer database
return {
type: 'postgres' as const,
host: process.env.DB_HOST,
port: +process.env.DB_PORT,
applicationName: 'app',
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
autoLoadEntities: true,
synchronize: IS_DEV,
logging: false,
};
},
});
This is because I use testcontainers
for my e2e tests and I mutate the process.env object in the beforeAll
hook of my test.
postgreSqlContainer = await new PostgreSqlContainer()
.withName('testcontainer')
.withDatabase('testcontainer')
.start();
//update database enviroment variables in order for typeorm to connect enter code hereto the testcontainer DB
process.env.DB_HOST = postgreSqlContainer.getHost();
process.env.DB_PORT = postgreSqlContainer.getPort().toString();
process.env.DB_USERNAME = postgreSqlContainer.getUsername();
process.env.DB_PASSWORD = postgreSqlContainer.getPassword();
process.env.DB_NAME = postgreSqlContainer.getDatabase();
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
server = request(app.getHttpServer());
This allows me to change the database connection credentials at runtime before the tests run.