9

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?

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Apart from whether somehow technically feasible or not, there probably is/was a reason the (base) class has been implemented readonly and therefore questionable if mocks are actually desired. That's not a judgement, just a note on considerations. E.g. I'd check if mocking can be prevented for testing, and if not, provide a mock/spy object for tests within the test suite for starters (not relying on dynamic mocks), YMMV.
If mocking/extending shall be prevented, the class is marked as "final". If I mark a class as "readonly" I still want to be able to mock it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.