From 71c4dd8b57d1ed9418e79dfad6d0c004d04cdaa9 Mon Sep 17 00:00:00 2001 From: Kevin Bui Date: Sun, 14 Dec 2025 19:11:12 +1100 Subject: [PATCH 1/3] Document macros and mixins for test responses. --- http-tests.md | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/http-tests.md b/http-tests.md index 1a23c3191a..1a8937d6ee 100644 --- a/http-tests.md +++ b/http-tests.md @@ -17,6 +17,9 @@ - [Response Assertions](#response-assertions) - [Authentication Assertions](#authentication-assertions) - [Validation Assertions](#validation-assertions) +- [Extending the Test Response](#extending-the-test-response) + - [Macros](#macros) + - [Mixins](#mixins) ## Introduction @@ -2072,3 +2075,78 @@ $response->assertInvalid([ 'email' => 'valid email address', ]); ``` + + +## Extending the Test Response + + +### Macros + +We are able to add our own methods, or macros, to the `Illuminate\Testing\TestResponse` class. The class's `macro` method accept a method name and a closure, which will be executed when this custom method is called. We can access the current test response via `$this`, as if it were a real method of the `Illuminate\Testing\TestResponse` class. + +For example, the following macros assert that JSON responses contain, or don't contain, a specific order object: + +```php +use App\Models\Order; +use Illuminate\Testing\TestResponse; + +TestResponse::macro('assertContain', function (Order $order) { + return $this->assertJson([ + 'id' => $order->id, + 'created_at' => $order->created_at, + ]); +}); + +TestResponse::macro('assertDontContain', function (Order $order) { + return $this->assertJsonMissing([ + 'id' => $order->id, + 'created_at' => $order->created_at, + ]); +}); +``` + +These macros can be defined at the `setUp` method for PHPUnit, the `beforeEach` method for Pest, or the `boot` method of a [service provider](/docs/{{version}}/providers). + +### Mixins + +In addition to macros. we can also add more functionality to the `Illuminate\Testing\TestResponse` class with it's `mixin` method. + +First, we define a new class with methods that we want to add to our test responses. Please note that those methods should not contain any parameters. The actual parameters and implementations will be part of the returned closures: + +```php +namespace App\Mixins; + +use App\Models\Order; + +class OrderAssertions +{ + public function assertContain() + { + return function (Order $order) { + return $this->assertJson([ + 'id' => $order->id, + 'created_at' => $order->created_at, + ]); + }; + } + + public function assertDontContain() + { + return function (Order $order) { + return $this->assertJsonMissing([ + 'id' => $order->id, + 'created_at' => $order->created_at, + ]); + }; + } +} +``` + +Then we can pass an instance of the above class to the `mixin` method. And the `Illuminate\Testing\TestResponse` class will have all the extra functionality: + +```php +use App\Mixins\OrderAssertions; +use Illuminate\Testing\TestResponse; + +TestResponse::mixin(new OrderAssertions); +``` \ No newline at end of file From 1a1c23a90f464541fdec680c1449cbf826add3e5 Mon Sep 17 00:00:00 2001 From: Kevin Bui Date: Sun, 14 Dec 2025 19:54:54 +1100 Subject: [PATCH 2/3] Small change. --- http-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-tests.md b/http-tests.md index 1a8937d6ee..c508d13cf8 100644 --- a/http-tests.md +++ b/http-tests.md @@ -2082,7 +2082,7 @@ $response->assertInvalid([ ### Macros -We are able to add our own methods, or macros, to the `Illuminate\Testing\TestResponse` class. The class's `macro` method accept a method name and a closure, which will be executed when this custom method is called. We can access the current test response via `$this`, as if it were a real method of the `Illuminate\Testing\TestResponse` class. +We are able to add our own methods, or macros, to the `Illuminate\Testing\TestResponse` class. The class's `macro` method accept a method name and a closure, which will be executed when this custom method is called. The closure can access the current test response via `$this`, as if it were a real method of the `Illuminate\Testing\TestResponse` class. For example, the following macros assert that JSON responses contain, or don't contain, a specific order object: From 87e87d2d6596de005b648f10555099a2c930c2f6 Mon Sep 17 00:00:00 2001 From: Kevin Bui Date: Sun, 14 Dec 2025 20:00:49 +1100 Subject: [PATCH 3/3] Small change to wording. --- http-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-tests.md b/http-tests.md index c508d13cf8..5cbea23fdc 100644 --- a/http-tests.md +++ b/http-tests.md @@ -2084,7 +2084,7 @@ $response->assertInvalid([ We are able to add our own methods, or macros, to the `Illuminate\Testing\TestResponse` class. The class's `macro` method accept a method name and a closure, which will be executed when this custom method is called. The closure can access the current test response via `$this`, as if it were a real method of the `Illuminate\Testing\TestResponse` class. -For example, the following macros assert that JSON responses contain, or don't contain, a specific order object: +For example, the following macros assert that JSON responses contain, or don't contain, a specific order model: ```php use App\Models\Order;