Testing
Resting plugs into PHPUnit via Laravel's testing utilities. The package itself is tested with PHPUnit 11 and Orchestra Testbench 9/10; consumer projects can use any compatible test stack.
Test-suite setup
Resting's own tests use Orchestra Testbench. If you're testing this package or building on top of it, your TestCase should look like:
use Orchestra\Testbench\TestCase as Orchestra;
use Seier\Resting\Support\Laravel\RestingServiceProvider;
use Seier\Resting\RestingSettings;
abstract class TestCase extends Orchestra
{
public function setUp(): void
{
parent::setUp();
RestingSettings::reset();
}
protected function getPackageProviders($app): array
{
return [RestingServiceProvider::class];
}
}Calling RestingSettings::reset() in setUp() ensures one test mutating the global serialization settings doesn't leak into the next.
assertNestedJsonValidationErrors
Resting registers an assertion macro on Laravel's TestResponse that reads the structured 422 envelope produced by the ->rest() middleware:
{
"message": "…",
"errors": {
"body": [
{ "path": "email", "message": "Field is required." }
],
"query": [],
"param": []
}
}Use the macro in feature tests to assert specific errors:
$this->postJson('/users', ['name' => 'Ada'])
->assertStatus(422)
->assertNestedJsonValidationErrors(['email']);You can pass:
- A flat array of paths — asserts each path appears in the error list.
- A
path => substringmap — asserts the path appears and its message contains the substring.
$this->postJson('/users', ['email' => ''])
->assertNestedJsonValidationErrors([
'email' => 'must', // message must contain "must"
]);By default the macro inspects errors.body. To check errors.query or errors.param, pass the group as the second argument:
->assertNestedJsonValidationErrors(['id'], 'param');
->assertNestedJsonValidationErrors(['page'], 'query');Constructing resources in tests
Resources have no required dependencies, so you can construct them inline:
$resource = (new UserResource())->set([
'name' => 'Ada',
'email' => 'ada@example.com',
'age' => 36,
]);
$this->assertSame('Ada', $resource->name->get());For testing predicates and conditional rules, instantiate the resource and feed it different inputs to confirm validation outcomes:
public function test_shipping_address_is_required_when_shipping(): void
{
$this->expectException(\Seier\Resting\Exceptions\ValidationException::class);
OrderResource::fromArray([
'requiresShipping' => true,
// shippingAddress missing
]);
}Asserting OpenAPI output
OpenAPI::toArray() returns plain arrays, which makes it easy to drill in:
$spec = (new OpenAPI(Route::getRoutes()))->toArray();
$this->assertArrayHasKey('UserResource', $spec['components']['schemas']);
$this->assertSame(['name', 'email'], $spec['components']['schemas']['UserResource']['required']);Running the package's own test suite
composer install
vendor/bin/phpunitThe CI workflow (.github/workflows/php.yml) runs the suite against PHP 8.2, 8.3, and 8.4.
What's next
- Validation — what assertions you might want to write.
- Routes & Macros — the response shape
assertNestedJsonValidationErrorsis built around.