Thanks to visit codestin.com
Credit goes to github.com

Skip to content

seamapi/ava-postgres

 
 

Repository files navigation

ava-postgres

ava-postgres is a test fixture for AVA that provides you with nearly-instant access to a fresh Postgres database for every test.

ava-postgres's only dependency is a running instance of Docker.

Installation

npm install --save-dev ava-postgres

or

yarn add --dev ava-postgres

Usage

ava-postgres's main export is a factory function, so you'll probably want to create a file like tests/fixtures/get-test-database.ts:

import { getTestPostgresDatabaseFactory } from "ava-postgres"

export const getTestDatabase = getTestPostgresDatabaseFactory({
  // Any tag for the official Postgres Docker image, defaults to "14"
  postgresVersion: "14",
})

Then, in your tests, you can use the getTestDatabase() function to get a fresh database for each test:

import test from "ava"
import { getTestDatabase } from "./fixtures/get-test-database"

test("foo bar", async (t) => {
  const { pool } = await getTestDatabase()

  await pool.query("SELECT 1")

  t.pass()
})

Full list of connection details returned by getTestDatabase

Database setup

ava-postgres uses Postgres templates so you only pay the setup cost once. After a template has been created, Postgres can create a new database from it in milliseconds.

If you want to perform common database setup, you can use a hook and pass parameters to the getTestDatabase() function:

import { getTestPostgresDatabaseFactory } from "ava-postgres"

type GetTestDatabaseParams = {
  shouldMigrate?: boolean
  shouldSeed?: boolean
}

export const getTestDatabase =
  getTestPostgresDatabaseFactory<GetTestDatabaseParams>({
    beforeTemplateIsBaked: async ({
      connection: { pool },
      params: { shouldMigrate, shouldSeed },
    }) => {
      if (shouldMigrate) {
        await pool.query("CREATE TABLE foo (id int)")
      }

      if (shouldSeed) {
        await pool.query("INSERT INTO foo VALUES (1)")
      }
    },
  })

Then, in your tests, you can pass parameters to the getTestDatabase() function:

import test from "ava"
import { getTestDatabase } from "./fixtures/get-test-database"

test("foo bar", async (t) => {
  const { pool } = await getTestDatabase({
    shouldMigrate: true,
    shouldSeed: true,
  })

  await pool.query("SELECT * FROM foo")

  t.pass()
})

Advanced Usage

Bind mounts & execing in the container

ava-postgres uses testcontainers under the hood to manage the Postgres container.

In some scenarios you might want to mount a SQL script into the container and manually load it using psql.

You can do this with the bindMounts option:

const getTestPostgresDatabase = getTestPostgresDatabaseFactory({
  container: {
    bindMounts: [
      {
        source: "/path/on/host",
        target: "/test.sql",
      },
    ],
  },
  beforeTemplateIsBaked: async ({
    connection: { username, database },
    containerExec,
  }) => {
    const { exitCode } = await containerExec(
      `psql -U ${username} -d ${database} -f /test.sql`.split(" ")
    )

    if (exitCode !== 0) {
      throw new Error(`Failed to load test file`)
    }
  },
})

About

🐘 instantly stand up full Postgres databases in your AVA tests

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 5