Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Troubles with mocking new PHP 8.2 readonly classes with PHPUnit test doubles

I try to mock readonly class from PHP 8.2 in PHPUnit and got next error:

Symfony\Component\ErrorHandler\Error\FatalError^ {#7 #message: "Compile Error: Non-readonly class Mock_Provider_f80b7c4d cannot extend readonly class App\Validator\Password\Rule\Provider" #code: 0 #file: "/var/www/html/teach-me/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php(51) : eval()'d code" #line: 3 -error: array:4 [ "type" => 64 "message" => "Non-readonly class Mock_Provider_f80b7c4d cannot extend readonly class App\Validator\Password\Rule\Provider" "file" => "/var/www/html/teach-me/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php(51) : eval()'d code" "line" => 3 ] }

I think this problem appears because PHPUnit creates default non-readonly class for mocked object. Is there a way to force the creation of a readonly class?

"phpunit/phpunit": "^9.5"

I removed readonly keyword from my class and this error disappeared. I would like to use the new features of PHP, but without the ability to mock objects, this is not possible. Perhaps I am doing something wrong and the problem is not at all what I think?

like image 551
Vitali Labatsevich Avatar asked May 29 '26 17:05

Vitali Labatsevich


1 Answers

If you couldn't find a solution, this might help: https://packagist.org/packages/zoltanka/bypass-readonly

That is not the best solution because essentially it changes the code and also makes the tests slower.

But I think it won't be possible soon to mock readonly classes because of how the mocked objects in PHPUnit work. They must hold some information that are changing after creation.

like image 77
Zoltán Fekete Avatar answered Jun 01 '26 07:06

Zoltán Fekete