Skip to main content
Version: v4.x.x

Database Testing with Poku and Prisma

End-to-end example of testing Poku and Prisma, from installing the client to spinning the database up with Docker Compose.

Open the connection in an outer describe, put every assertion inside its own it, and disconnect at the end of that same describe, so cleanup always runs regardless of what an individual assertion does. The container lifecycle lives in a poku.config.js anonymous plugin that uses @pokujs/docker to run setup before the suite and teardown after it, so the suite runs with a plain npm test.

Install​

npm i @prisma/client
npm i -D poku tsx @pokujs/docker prisma

Configure the credentials​

.env.test:

DB_USER=postgres
DB_PASSWORD=secret
DB_PORT=5432
DB_NAME=app
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@localhost:${DB_PORT}/${DB_NAME}"

.gitignore:

.env.test

Start the database​

docker-compose.yml reads the same .env.test to configure the container:

services:
postgres:
image: postgres:18
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- '${DB_PORT}:5432'
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${DB_USER} -d ${DB_NAME}']
interval: 5s
timeout: 5s
retries: 10
start_period: 30s

db-ready:
image: busybox
command: ['tail', '-f', '/dev/null']
depends_on:
postgres:
condition: service_healthy

Define the schema​

prisma/schema.prisma reads the connection string from the environment:

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

generator client {
provider = "prisma-client-js"
}

model User {
id Int @id
name String
}

Connect​

db.ts:

import { PrismaClient } from '@prisma/client';

export const prisma = new PrismaClient();

Write the test​

users.test.ts:

import { describe, it, assert } from 'poku';
import { prisma } from './db.js';

await describe('User model', async () => {
await describe('Seed', async () => {
await prisma.user.create({ data: { id: 1, name: 'Poku' } });
});

await it('reads the created user', async () => {
const user = await prisma.user.findUnique({ where: { id: 1 } });

assert.strictEqual(user?.name, 'Poku', 'The created user is returned');
});

await prisma.$disconnect();
});

Configure Poku​

poku.config.js:

import { execSync } from 'node:child_process';
import { defineConfig } from 'poku';
import { docker } from '@pokujs/docker';

const compose = docker.compose({ envFile: '.env.test' });

export default defineConfig({
envFile: '.env.test',
sequential: true,
plugins: [
{
setup: async () => {
await compose.up();
execSync('npx prisma db push --skip-generate', { stdio: 'inherit' });
},
teardown: () => compose.down(),
},
],
});
tip

Configuring Poku is optional: you can orchestrate your containers however you prefer and run Poku as poku --envFile='.env.test' --sequential, for example. In that case, @pokujs/docker is not needed.

Run​

Add the test script to package.json:

{
"scripts": {
"test": "poku"
}
}

Then generate the client and run it:

npx prisma generate
npm test