Last active
September 16, 2022 21:03
-
-
Save ali-kamalizade/f4347dc53ac59bdfbed0131ca710fcda to your computer and use it in GitHub Desktop.
A function to create a Postgres container with Testcontainers. Written in TypeScript.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { GenericContainer, StartedTestContainer } from 'testcontainers'; | |
import { AbstractStartedContainer } from 'testcontainers/dist/modules/abstract-started-container'; | |
import { RandomUuid } from 'testcontainers/dist/uuid'; | |
const POSTGRES_PORT = 5432; | |
export async function createDatabaseContainer() { | |
// reusing the same container for all tests is considerably faster than starting a new one for each test | |
const container = await new PostgreSqlContainer().withReuse().start(); | |
const host = container.getHost(); | |
const port = container.getPort(); | |
const database = container.getDatabase(); | |
const user = container.getUsername(); | |
const password = container.getPassword(); | |
// needed later to retrieve the current container, so it can be stopped and removed after the tests have run | |
process.env.TEST_POSTGRES_CONTAINER_ID = container.getId(); | |
// the database client (e.g. Prisma) uses this to connect to the database | |
process.env.POSTGRES_DATABASE_URL = `postgresql://${user}:${password}@${host}:${port}/${database}?schema=public`; | |
// do anything else: e.g. run database migrations | |
return container; | |
} | |
export class PostgreSqlContainer extends GenericContainer { | |
private database = 'test'; | |
private username = new RandomUuid().nextUuid(); | |
private password = new RandomUuid().nextUuid(); | |
constructor(readonly image = 'postgres:14.2-alpine') { | |
super(image); | |
} | |
public async start(): Promise<StartedPostgreSqlContainer> { | |
this.withExposedPorts(...(this.hasExposedPorts ? this.ports : [POSTGRES_PORT])) | |
.withEnv('POSTGRES_DB', this.database) | |
.withEnv('POSTGRES_USER', this.username) | |
.withEnv('POSTGRES_PASSWORD', this.password) | |
.withStartupTimeout(120_000); | |
return new StartedPostgreSqlContainer(await super.start(), this.database, this.username, this.password); | |
} | |
} | |
export class StartedPostgreSqlContainer extends AbstractStartedContainer { | |
private readonly port: number; | |
constructor( | |
readonly startedTestContainer: StartedTestContainer, | |
private readonly database: string, | |
private readonly username: string, | |
private readonly password: string | |
) { | |
super(startedTestContainer); | |
this.port = startedTestContainer.getMappedPort(POSTGRES_PORT); | |
} | |
public getPort() { | |
return this.port; | |
} | |
public getDatabase() { | |
return this.database; | |
} | |
public getUsername() { | |
return this.username; | |
} | |
public getPassword() { | |
return this.password; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment