Lawhive Framework
Testing

Testing

Test harness and fixtures for integration testing with real databases

The @lawhive/framework-testing package provides a composable test harness for integration tests that need real infrastructure like PostgreSQL and Prisma.

Philosophy

Integration tests should:

  • Use real databases - Mocks hide real bugs
  • Be isolated - Each test suite gets fresh infrastructure
  • Be composable - Mix and match fixtures as needed
  • Be fast - Testcontainers for quick spinup/teardown

Installation

bun add -D @lawhive/framework-testing

Quick Start

import { describe, it, expect, beforeEach } from "vitest"
import { buildHarness, postgresContainer, bootstrapPrisma } from "@lawhive/framework-testing"
import { PrismaClient } from "./generated/client"

const ctx = buildHarness()
  .use(() => ({
    pg: postgresContainer({ image: "postgres:16-alpine" }),
  }))
  .use(({ pg }) => ({
    prisma: bootstrapPrisma({
      client: PrismaClient,
      schemaPath: "./prisma/schema.prisma",
      connectionString: pg.connectionString,
    }),
  }))
  .setup()

describe("Task", () => {
  beforeEach(async () => {
    await ctx.prisma.task.deleteMany()
  })

  it("creates a task", async () => {
    const task = await ctx.prisma.task.create({
      data: { name: "Test Task" },
    })

    expect(task.name).toBe("Test Task")
  })
})

How It Works

  1. Container Spinup - PostgreSQL container starts in beforeAll
  2. Schema Push - Prisma schema is pushed to the container
  3. Test Execution - Tests run against real database
  4. Cleanup - Container is destroyed in afterAll

Features

  • Composable fixtures - Chain .use() calls to build context
  • Dependency injection - Each .use() receives previous fixtures
  • Automatic cleanup - Fixtures clean up in reverse order
  • Type safety - Full TypeScript inference for context
  • Test runner agnostic - Works with Vitest, Jest, Bun test

Next Steps