Skip to content

Instantly share code, notes, and snippets.

@navjotahuja92
Last active February 12, 2025 10:06
Show Gist options
  • Save navjotahuja92/f51601b17fb248cf4727b5650d945607 to your computer and use it in GitHub Desktop.
Save navjotahuja92/f51601b17fb248cf4727b5650d945607 to your computer and use it in GitHub Desktop.
Nest.js Test Setup with In Memory Postgres Database (pg-mem)
// Install npm i pg-mem --save-dev
import { DataSource, Repository } from 'typeorm';
import { newDb, DataType } from 'pg-mem';
import { v4 } from 'uuid';
const setupDataSource = async () => {
const db = newDb({
autoCreateForeignKeyIndices: true,
});
db.public.registerFunction({
implementation: () => 'test',
name: 'current_database',
});
db.registerExtension('uuid-ossp', (schema) => {
schema.registerFunction({
name: 'uuid_generate_v4',
returns: DataType.uuid,
implementation: v4,
impure: true,
});
});
const ds: DataSource = await db.adapters.createTypeormDataSource({
type: 'postgres',
entities: [__dirname + '/../../src/**/*.entity{.ts,.js}'],
});
await ds.initialize();
await ds.synchronize();
return ds;
};
export const buildTestingModule = async () => {
if (testingModule) {
return testingModule;
}
const dataSource = await setupDataSource();
testingModule = await Test.createTestingModule({
imports: [
TypeOrmModule.forRoot({
name: 'default',
synchronize: true,
}),
CoreModule,
],
})
.overrideProvider(DataSource)
.useValue(dataSource)
.compile();
return testingModule;
};
@theusindabike
Copy link

Same here! Thanks folks!

@doyeka
Copy link

doyeka commented Aug 16, 2023

Huge thanks. Do you mind explaining why you chose { name: 'default', synchronize: true, } for the TypeOrmModuleOptions argument?

I was also trying to inject the provider using { getDataSourceToken } from "@nestjs/typeorm". I wonder why overriding the provider versus injecting it makes a difference.

@skapxd
Copy link

skapxd commented Nov 23, 2024

This work for me

import { randomUUID } from 'node:crypto';

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DataType, newDb } from 'pg-mem';
import { DataSource } from 'typeorm';
import {
  Column,
  CreateDateColumn,
  Entity,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from 'typeorm';

import { AppController } from './app.controller';
import { AppService } from './services/app.service';
import { EntityClasses } from './utility-types/entity';

@Entity('dollars')
export class Dollar {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ type: 'decimal' })
  value: number;

  @CreateDateColumn({ type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
  createdAt: Date;

  @UpdateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
    onUpdate: 'CURRENT_TIMESTAMP',
  })
  updatedAt: Date;
}

export const setupDataSource = async (entities: EntityClasses) => {
  const db = newDb({
    autoCreateForeignKeyIndices: true,
  });

  db.public.registerFunction({
    implementation: () => 'test',
    name: 'current_database',
  });

  db.registerExtension('uuid-ossp', (schema) => {
    schema.registerFunction({
      name: 'uuid_generate_v4',
      returns: DataType.uuid,
      implementation: randomUUID,
      impure: true,
    });
  });

  db.public.registerFunction({
    name: 'version',
    implementation: () => 'PostgreSQL 13.3',
  });

  const ds: DataSource = await db.adapters.createTypeormDataSource({
    type: 'postgres',
    entities,
  });

  await ds.initialize();
  await ds.synchronize();

  return ds;
};

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useFactory: async () => {
        return {
          name: 'default',
          synchronize: true,
        };
      },
      dataSourceFactory: async () => {
        const dataSource = await setupDataSource([Dollar]);
        return dataSource;
      },
    }),
    TypeOrmModule.forFeature([Dollar]),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment