Installation Add the package via Composer:
composer require --dev cloudcreativity/json-api-testing
No additional configuration is required—it works out-of-the-box with PHPUnit.
First Use Case: Basic JSON API Assertion
Use the JsonApiTestCase trait in your test class to validate JSON:API responses:
use CloudCreativity\JsonApiTesting\JsonApiTestCase;
class UserApiTest extends JsonApiTestCase
{
public function test_user_response()
{
$response = $this->get('/api/users/1');
$this->assertJsonApiResponse($response)
->hasData('users', 1)
->hasAttributes('users.0', ['name', 'email'])
->isValid();
}
}
Key Methods to Explore First
assertJsonApiResponse(): Entry point for assertions.hasData(): Verify resource count.hasAttributes(): Check for required fields.isValid(): Ensure the response adheres to JSON:API spec.Testing API Endpoints Chain assertions for comprehensive validation:
$this->assertJsonApiResponse($response)
->hasData('articles', 2)
->hasRelationships('articles.0', ['author'])
->hasMeta('pagination', ['total', 'limit'])
->isValid();
Dynamic Data Validation Use closures for conditional checks:
$this->assertJsonApiResponse($response)
->hasAttributes('users.0', function ($attributes) {
return $attributes['email'] === '[email protected]';
});
Testing Error Responses Validate error formats (e.g., 404, 422):
$response = $this->get('/api/nonexistent');
$this->assertJsonApiResponse($response)
->hasErrors(['detail' => 'Not Found'])
->isInvalid();
Integration with Laravel HTTP Tests
Combine with Laravel’s Http\TestResponse for seamless testing:
$response = $this->actingAs($user)->post('/api/posts', ['title' => 'Test']);
$this->assertJsonApiResponse($response)
->hasData('posts', 1)
->hasAttribute('posts.0', 'title', 'Test');
Custom Assertions Extend the package for domain-specific rules:
$this->assertJsonApiResponse($response)
->hasCustomValidation('posts.0', function ($post) {
$this->assertTrue(str_contains($post['title'], 'Laravel'));
});
Strict JSON:API Compliance
The package enforces JSON:API spec rules (e.g., data root key, type/id fields). If your API deviates, assertions may fail unexpectedly.
Fix: Use isValid(false) to skip spec validation.
Nested Resource Traversal
Incorrect path syntax (e.g., users.0.author) will throw errors.
Tip: Use hasRelationships() for nested resources and verify paths carefully.
Case Sensitivity
Attribute names in hasAttributes() are case-sensitive.
Tip: Normalize keys (e.g., snake_case) in tests if your API uses them.
Meta/Data Confusion
Mixing meta and data assertions can lead to false positives.
Tip: Explicitly scope checks (e.g., hasMeta(), hasData()).
$response->getContent() to debug unexpected JSON structures.isValid(false) to isolate issues.users.0).Custom Validators
Override JsonApiTestCase to add domain logic:
protected function customValidations()
{
return [
'posts.0' => function ($post) {
$this->assertTrue($post['published_at'] > now());
}
];
}
Mocking Responses
Use Laravel’s JsonResponse for unit tests:
$mockResponse = new JsonResponse(['data' => [...]]);
$this->assertJsonApiResponse($mockResponse)->isValid();
Performance
For large datasets, cache responses or use only() to limit assertions:
$this->assertJsonApiResponse($response)
->only(['data', 'meta'])
->isValid();
How can I help you explore Laravel packages today?