diff --git a/src/Illuminate/Database/Eloquent/Concerns/PreventsCircularRecursion.php b/src/Illuminate/Database/Eloquent/Concerns/PreventsCircularRecursion.php index 27d69a98b1ae..85aa66d9cedc 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/PreventsCircularRecursion.php +++ b/src/Illuminate/Database/Eloquent/Concerns/PreventsCircularRecursion.php @@ -28,6 +28,10 @@ protected function withoutRecursion($callback, $default = null) $onceable = Onceable::tryFromTrace($trace, $callback); + if (is_null($onceable)) { + return call_user_func($callback); + } + $stack = static::getRecursiveCallStack($this); if (array_key_exists($onceable->hash, $stack)) { diff --git a/tests/Database/DatabaseConcernsPreventsCircularRecursionTest.php b/tests/Database/DatabaseConcernsPreventsCircularRecursionTest.php index c04e85957718..a35a6cd19447 100644 --- a/tests/Database/DatabaseConcernsPreventsCircularRecursionTest.php +++ b/tests/Database/DatabaseConcernsPreventsCircularRecursionTest.php @@ -3,6 +3,7 @@ namespace Illuminate\Tests\Database; use Illuminate\Database\Eloquent\Concerns\PreventsCircularRecursion; +use Mockery; use PHPUnit\Framework\TestCase; class DatabaseConcernsPreventsCircularRecursionTest extends TestCase @@ -172,6 +173,18 @@ public function testRecursiveCallsToCircularLinkedListCallsEachInstanceOnce() $this->assertEquals(3, $second->instanceStack); $this->assertEquals(3, $third->instanceStack); } + + public function testMockedModelCallToWithoutRecursionMethodWorks(): void + { + $mock = Mockery::mock(TestModel::class)->makePartial(); + + // Model toArray method implementation + $toArray = $mock->withoutRecursion( + fn () => array_merge($mock->attributesToArray(), $mock->relationsToArray()), + fn () => $mock->attributesToArray(), + ); + $this->assertEquals([], $toArray); + } } class PreventsCircularRecursionWithRecursiveMethod