---
name: phpunit-tests
description: >
  Generate high-quality PHPUnit unit tests for small MVC PHP applications (no framework).
  Use when: (1) PHP classes need test coverage, (2) user asks to generate unit tests,
  (3) code review reveals missing tests, (4) "PHPUnit", "unit tests", "test coverage" mentioned for PHP code.
  Targets PHP 8.2+, strict types, PHPUnit only. All dependencies mocked. No integration tests.
---

# PHPUnit Test Generation

## Architecture

```
app/
  Controllers/
  Models/
  Services/
  Repositories/
  Helpers/
tests/
```

No heavy framework (no Laravel, Symfony, CodeIgniter). Pure PHP-MVC.

## Test Rules

- PHPUnit only. Real unit tests. No integration tests.
- No real database connections. No real HTTP requests.
- Always mock or stub external dependencies. Never mock the class under test.
- Tests must be independent. Each test checks exactly one behavior.
- AAA pattern: Arrange → Act → Assert.
- Descriptive method names: `testReturnsUserWhenIdExists`, `testThrowsExceptionWhenPasswordInvalid`.
- Small, readable, deterministic tests. No global state. No random values without fixed seeds.

## Code Standards

- PHP >= 8.2, typed properties, `declare(strict_types=1)`.
- Modern PHPUnit syntax. No deprecated APIs.
- No unnecessary comments. No reflection. No magic.
- PSR-compliant. Copy-paste runnable. Production-ready.

## Mocking

- Use PHPUnit mock objects for direct dependencies only.
- Define mock behavior explicitly. Validate method calls when meaningful.
- Services → mock repository dependencies.
- Controllers → simulate HTTP input.
- Helpers → test pure function logic.

## Output Format

1. Brief analysis of the class under test.
2. List of relevant test cases.
3. Complete PHPUnit test code (directly runnable).
4. If needed: mock setup, test fixtures, data providers.

## Complex Logic

- List test cases first, then write tests.
- Test edge cases for validation logic.
- Always explicitly check exceptions.
- If information is missing: make reasonable assumptions and document them briefly before the test code.

## Anti-Patterns

- One giant test for everything.
- Too many assertions per test.
- Hidden side effects.
- Framework-specific test helpers.
