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:
- RED: Test that missing title returns 400
- GREEN: Implement validation
- RED: Test success case returns 201 with post
- GREEN: Implement creation
- RED: Test unauthenticated returns 401
- 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 routeTry it yourself — TYPESCRIPT