Payload CMS v3+ Utility

Test API Routes in Milliseconds

An elegant, in-process Axios tester for Payload CMS. Say goodbye to slow Next.js dev server starts, network overhead, and flaky port conflicts.

Traditional Testing
pnpm run dev
▲ Next.js 15.0.0 (Turbo)
Local server running on port 3000...
✓ Built in 4.8s
⚠️ Port 3000 already in use, trying 3001...
Running tests against localhost:3001...
Time: ~5.2 seconds
In-Process Testing
pnpm test
✓ tests/api.test.ts (8/8 passed)
🚀 Direct route matched: GET /api/posts/featured
⚡ Database transaction context propagated
✓ All tests completed in memory
Time: 12ms (400x faster)

Tested Features, Unleashed Speed

Everything you need to test Payload CMS endpoint integrations completely in-memory.

In-Process Routing

Intercept requests locally and resolve them directly using Payload's sanitized configurations, cutting network overhead entirely.

Authentication Resolution

Pass standard JWT auth headers. The adapter resolves the payload user session and populates req.user automatically.

Database Transactions

Ensures real SQLite or PostgreSQL transaction states flow properly into collection hooks, exactly like production environments.

Request Mutator Hooks

Use the requestPatcher hook to modify, inject headers, or mock session parameters right before they reach route handlers.

Fully Type-Safe

Built native in TypeScript. Autocomplete, interface definitions, and IDE hints make test setup clean and straightforward.

Standard Axios Instance

Configure timeout, headers, retry interceptors, and default status validations directly on a standard Axios client instance.

Zero Boilerplate

Setting up tests is as easy as wrapping your standard config with createTesterAxios. It feels just like writing HTTP tests, minus the latency.

Install Package

pnpm add -D payload-test-api-route-handler
api-route.test.ts
import { describe, it, expect, beforeAll } from 'vitest';
import { getPayload } from 'payload';
import { buildConfig } from 'payload';
import { createTesterAxios } from 'payload-test-api-route-handler';

describe('API Routes', () => {
  let config;

  beforeAll(async () => {
    config = await buildConfig({
      // Standard configuration settings...
      db: sqliteAdapter({ client: { url: 'file::memory:' } }),
      secret: 'test-secret-at-least-32-chars-long',
    });
    await getPayload({ config });
  });

  it('performs fast in-memory get requests', async () => {
    // 1. Create client instance mapped to your config
    const client = createTesterAxios(config);

    // 2. Call local endpoints directly
    const res = await client.get('/api/posts/featured');

    // 3. Make assertions in milliseconds!
    expect(res.status).toBe(200);
    expect(res.data.featured).toBe(true);
  });
});

Upgrade Your Test Velocity

Run your integration suites at the speed of unit tests today.