I recently received a bug report for PHPUnit [1] that with PHP 8 test
doubles (test stubs or mock objects) can no longer be created for
interfaces that declare a constructor.
I was able to reproduce this [2] and learned that PHPUnit's
canMockMethod() [3] returns a different result on PHP 8 compared to PHP
- This is due to the return value of ReflectionMethod::isConstructor()
when the ReflectionMethod object was created for an interface.
Here is a minimal, self-contained, reproducing test case:
<?php
interface I
{
public function __construct();
}
var_dump((new ReflectionMethod(I::class, '__construct'))->isConstructor());
The code shown above yields the following result:
- bool(true) for PHP 5.0.0 and PHP 5.0.1
- bool(false) for PHP 5.0.2 through PHP 7.4.4
- bool(true) for PHP 8.0-dev
I think that the behaviour in PHP 8 (and PHP 5.0.0 and PHP 5.0.1) is
correct. But I also think that constructor declarations have no place in
interfaces ... so I am confused. Which is why I did not open a ticket on
bugs.php.net and bring this topic to this list instead.
To the best of my knowledge, this change in behaviour of isConstructor()
between PHP 7 and PHP 8 is not yet documented. If it is intentional and
here to stay then it should be documented.
I can deal with this in PHPUnit's code either way, but need to know what
the plan here is.
Thanks!
Sebastian
--
[1] https://github.com/sebastianbergmann/phpunit/issues/4139
[2]
https://github.com/sebastianbergmann/phpunit/issues/4139#issuecomment-605407253
[3]
https://github.com/sebastianbergmann/phpunit/blob/9.0.1/src/Framework/MockObject/Generator.php#L861
Am 28.03.2020 um 08:44 schrieb Sebastian Bergmann:
<?php
interface I
{
public function __construct();
}var_dump((new ReflectionMethod(I::class, '__construct'))->isConstructor());
Here is the version of the script for testing with dead versions of PHP:
https://3v4l.org/fMCub
I recently received a bug report for PHPUnit [1] that with PHP 8 test
doubles (test stubs or mock objects) can no longer be created for
interfaces that declare a constructor.I was able to reproduce this [2] and learned that PHPUnit's
canMockMethod() [3] returns a different result on PHP 8 compared to PHP
- This is due to the return value of ReflectionMethod::isConstructor()
when the ReflectionMethod object was created for an interface.Here is a minimal, self-contained, reproducing test case:
<?php
interface I
{
public function __construct();
}var_dump((new ReflectionMethod(I::class, '__construct'))->isConstructor());
The code shown above yields the following result:
- bool(true) for PHP 5.0.0 and PHP 5.0.1
- bool(false) for PHP 5.0.2 through PHP 7.4.4
- bool(true) for PHP 8.0-dev
I think that the behaviour in PHP 8 (and PHP 5.0.0 and PHP 5.0.1) is
correct. But I also think that constructor declarations have no place in
interfaces ... so I am confused. Which is why I did not open a ticket on
bugs.php.net and bring this topic to this list instead.To the best of my knowledge, this change in behaviour of isConstructor()
between PHP 7 and PHP 8 is not yet documented. If it is intentional and
here to stay then it should be documented.I can deal with this in PHPUnit's code either way, but need to know what
the plan here is.
The relevant change[1] is that now the class entry members
serialize_func, unserialize_func, constructor, destructor and clone are
set, if the respective methods are declared on an interface.
[1]
https://github.com/php/php-src/pull/3846/files#diff-3a8139128d4026ce0cb0c86beba4e6b9L5549-R5605
--
Christoph M. Becker
Am 28.03.2020 um 08:44 schrieb Sebastian Bergmann:
I can deal with this in PHPUnit's code either way, but need to know what
the plan here is.
I worked around the issue now [1].
--
[1]
https://github.com/sebastianbergmann/phpunit/commit/477798f6b226e830d358bc102cd02bb2e52cfdb2
Hey Sebastian,
http://ocramius.github.com/
On Mon, Mar 30, 2020 at 8:45 AM Sebastian Bergmann sebastian@php.net
wrote:
Am 28.03.2020 um 08:44 schrieb Sebastian Bergmann:
I can deal with this in PHPUnit's code either way, but need to know what
the plan here is.I worked around the issue now [1].
--
[1]https://github.com/sebastianbergmann/phpunit/commit/477798f6b226e830d358bc102cd02bb2e52cfdb2
Patch makes a lot of sense, but is it done that way to still support 7.x?
I'm not sure (don't have a local build of PHP 8.x-dev) if
https://wiki.php.net/rfc/remove_php4_constructors is going to come in
effect as "PHP4 constructors are finally gone".
Marco Pivetta
Am 30.03.2020 um 10:14 schrieb Marco Pivetta:
Patch makes a lot of sense, but is it done that way to still support 7.x?
I'm not sure (don't have a local build of PHP 8.x-dev) if
https://wiki.php.net/rfc/remove_php4_constructors is going to come in
effect as "PHP4 constructors are finally gone".
https://github.com/sebastianbergmann/phpunit/commit/8d399fd561a9a227898fb734c9e89fa1b13d75c8
:-)