Testing
Running the suite
php mitosis test delegates to the bundled PHPUnit — no bespoke test runner. The same
command is also available as a Composer script:
php mitosis test
# or
composer run test
Tests live in resources/tests/, mirroring the namespace of the code they cover.
No real database required
resources/tests/bootstrap.php (wired via phpunit.xml.dist's
bootstrap attribute) sets the small amount of ambient state a few middleware stubs read
at construction — APP_SECRET, the APP constant — without touching
.env or a real database connection:
<?php
declare(strict_types=1);
require __DIR__ . '/../../vendor/autoload.php';
putenv('APP_SECRET=test-suite-secret-do-not-use-in-production');
putenv('APP_NAME=Test App');
putenv('BASE_URL=http://127.0.0.1');
require __DIR__ . '/../../config/dir.php';
A test that touches the database opens its own in-memory SQLite connection and runs the real migrations against it — no fixtures file, no seeded test database to keep in sync:
use Monad\Clarity\Services\DB;
use Monad\Clarity\Services\Migration;
use PHPUnit\Framework\Attributes\Before;
#[Before]
public function setUpDatabase(): void
{
DB::useConnection(new PDO('sqlite::memory:'));
Migration::migrate(dirname(__DIR__, 3) . '/database/migrations');
}
Testing a route
Routes are tested the same way public/index.php runs them in production —
Route::dispatch() against a real Request, no HTTP server involved:
use Monad\Clarity\Services\Request;
use Monad\Clarity\Services\Route;
public function testGreetingRouteReturnsTheNameFromTheUrl(): void
{
Route::reset();
require dirname(__DIR__, 2) . '/app/routes/web.php';
$request = Request::fromArrays(
server: ['REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/hello/Marshal', 'HTTP_HOST' => '127.0.0.1'],
);
$response = Route::dispatch($request);
self::assertSame(200, $response->status());
self::assertStringContainsString('Hello, Marshal!', $response->content());
}
This is the same pattern as the Quickstart route — write this test
once /hello/{name} exists and it exercises the exact code path a real request would.
Next steps
- Routing — the full
RouteAPI this pattern dispatches against. - Deployment —
php mitosis health, the same acceptance gate CI should run before a deploy. - FAQ — common questions about the test tooling, including what
mitosisdoes and doesn't generate for you.