wp-phpunit-redirect-harnesslisted
Install: claude install-skill mralaminahamed/wp-dev-skills
# PHPUnit Harness for `wp_safe_redirect(); exit;`
## The problem
Production code commonly does:
```php
wp_safe_redirect( $url );
exit;
```
Under PHPUnit, `add_filter( 'wp_redirect', '__return_false' )` stops the header but **does NOT stop `exit`** — the next statement runs and terminates the whole PHP process. PHPUnit dies mid-run: exit code 0, no `Tests: N` summary, and every test after the first redirect test silently never runs. Symptom: "the suite passes but prints no summary" or "stops at ~N%".
## The fix — throw instead of redirect, catch instead of exit
Throwing from the `wp_redirect` filter unwinds the stack **before** `exit;` is reached.
### 1. A shared exception (own PSR-4 file so both unit + integration tests can use it)
```php
namespace MyPlugin\Test;
class Redirect extends \Exception {
public string $location;
public function __construct( string $location ) {
parent::__construct( 'redirect' );
$this->location = $location;
}
}
```
Put it in its own file (e.g. `tests/.../Redirect.php`) so the autoloader finds it regardless of which test file loads first — never inline in one test file.
### 2. Throwing filter in `set_up`, removed in `tear_down`
```php
$this->redirect_filter = static function ( $location ) {
throw new Redirect( (string) $location );
};
add_filter( 'wp_redirect', $this->redirect_filter, 10, 1 );
// tear_down: remove_filter( 'wp_redirect', $this->redirect_filter, 10 );
```
### 3. A run helper that catches it