estahn/phpunit-json-assertions
Expressive JSON assertions for PHPUnit. Verify API responses and JSON documents by structure, values, and types without manually decoding payloads or hand-checking nested arrays. Works with existing test cases to keep your suite readable, precise, and concise.
composer require --dev estahn/phpunit-json-assertions.TestResponse macro.vendor/estahn/phpunit-json-assertions/src/JsonAssertions.php for the exact trait and method names,composer.json for PHPUnit and JSON Schema validator constraints,First use case: lock down one API response contract.
use Estahn\JsonAssertions\JsonAssertions;
use Illuminate\Foundation\Testing\TestCase;
class UserApiTest extends TestCase
{
use JsonAssertions;
public function test_user_show_matches_schema(): void
{
$response = $this->getJson('/api/users/1');
$response->assertOk();
$this->assertJsonStringMatchesJsonSchema(
$response->getContent(),
file_get_contents(base_path('tests/Schemas/user.json'))
);
}
}
Confirm the schema assertion method name in the installed trait version. The package has been dormant since 2021, so the vendor source is the source of truth.
tests/Schemas or tests/Contracts, organized by API version and endpoint.tests/Schemas/v1/user.json
tests/Schemas/v1/user-list.json
tests/Schemas/v1/error.json
TestCase so individual tests stay readable.protected function assertJsonResponseMatchesSchema(
\Illuminate\Testing\TestResponse $response,
string $schemaPath
): void {
$response->assertOk();
$this->assertJsonStringMatchesJsonSchema(
$response->getContent(),
file_get_contents(base_path($schemaPath))
);
}
assertJsonPath, assertJsonFragment, and assertJsonCount for specific values./**
* @dataProvider endpointSchemaProvider
*/
public function test_endpoint_matches_schema(string $uri, string $schema): void
{
$response = $this->getJson($uri);
$response->assertOk();
$this->assertJsonStringMatchesJsonSchema(
$response->getContent(),
file_get_contents(base_path($schema))
);
}
$response->getContent(). Avoid re-encoding $response->json() unless your assertion method requires an array; re-encoding can hide empty-object versus empty-array issues.required, type, and properties; add format, enum, and additionalProperties only where the contract really demands it.$defs/definitions and $ref, but keep $ref paths simple and absolute enough for the validator to resolve reliably.$response->assertJsonSchema(). Build that helper yourself on TestCase.json_decode($json, true, 512, JSON_THROW_ON_ERROR) in debugging or in your helper.$ref resolution is a common failure point. Relative refs may resolve from the process working directory rather than the schema file location. Prefer inline schemas for small cases, or absolute file paths/URIs for shared definitions."type": "object" or "type": "array".required means present, not non-null. Add "type": "string" or similar if nulls are invalid.How can I help you explore Laravel packages today?