Test-Driven Development

TDD for API Routes and Server Actions

Apply TDD to backend code — where precise input/output definitions make test-first development natural.

Backend TDD: Where It Shines

TDD for API routes is where the methodology produces the clearest benefits. API behavior is perfectly expressed as input/output contracts:

  • Given this input → expect this response code and body
  • Given invalid input → expect this error response
  • Given unauthenticated request → expect 401

Testing Next.js API Routes

Test API route handlers directly — no HTTP server needed. Import the route handler function and call it with a mock NextRequest object.

TDD Cycle for a Create Post API

Build the API incrementally with TDD:

  1. RED: Test that missing title returns 400
  2. GREEN: Implement validation
  3. RED: Test success case returns 201 with post
  4. GREEN: Implement creation
  5. RED: Test unauthenticated returns 401
  6. GREEN: Add authentication check

Mocking the Database

For unit-level API tests, mock the database using vi.mock(). Verify both the response status and the database call arguments. For integration tests, use a real test database.

Key Takeaways

  • API routes are the ideal target for TDD — behavior maps perfectly to input/output contracts
  • Test route handlers directly by calling the exported function with a mock NextRequest
  • Write one test per requirement: validation, success, authorization, error cases
  • Mock the database for unit tests; use a real test database for integration tests
  • TDD naturally produces comprehensive API route tests covering all HTTP status codes

Example

typescript
// TDD for a create comment API route
Try it yourself — TYPESCRIPT