phpunit: PHPUnit_Framework_TestCase::createConfiguredMock() doesn't mock protected methods
| Q | A |
|---|---|
| PHPUnit version | 6.0.8 |
| PHP version | 7.1.2 |
| Installation Method | Composer |
Currently, PHPUnit\Framework\TestCase::createConfiguredMock() doesn’t mock protected methods, and judging by the error message it’s not the expected behavior. It’s also unexpected as technically it is possible to mock a protected method if it’s specified during mock initialization.
Consider the following test:
<?php
use PHPUnit\Framework\TestCase;
class SUT
{
public function foo()
{
return $this->bar();
}
protected function bar()
{
return 'bar';
}
}
class ConfiguredMockTest extends TestCase
{
public function testMockProtectedMethodUsingPartialMock()
{
$mock = $this->createPartialMock(SUT::class, ['bar']);
$mock->method('bar')->willReturn('baz');
$this->assertEquals('baz', $mock->foo());
}
public function testMockProtectedMethodUsingConfiguredMock()
{
$mock = $this->createConfiguredMock(SUT::class, [
'bar' => 'baz'
]);
$this->assertEquals('baz', $mock->foo());
}
}
It produces the following output:
There was 1 warning:
1) ConfiguredMockTest::testMockProtectedMethodUsingConfiguredMock
Trying to configure method "bar" which cannot be configured because it does not exist, has not been specified, is final, or is static
/home/morozov/Projects/phpunit/src/Framework/TestResult.php:701
/home/morozov/Projects/phpunit/src/Framework/TestCase.php:867
/home/morozov/Projects/phpunit/src/Framework/TestSuite.php:739
/home/morozov/Projects/phpunit/src/Framework/TestSuite.php:739
/home/morozov/Projects/phpunit/src/Framework/TestSuite.php:739
/home/morozov/Projects/phpunit/src/TextUI/TestRunner.php:514
/home/morozov/Projects/phpunit/src/TextUI/Command.php:207
/home/morozov/Projects/phpunit/src/TextUI/Command.php:136
However, SUT::bar() exists, was specified, it’s not final or static.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (2 by maintainers)
@morozov
TestCase::createConfiguredMock()creates a full mock. That is, all (!) methods are mocked, and the configured methods will return the specified return values.How much sense does it make to configure a
protectedmethod of a full mock, when all of thepublicmethods are mocked, and none of them actually have a chance to invoke the protected method?Adjusting
TestCase::createConfiguredMock()to mock the specified methods only, instead of all of them, will break existing behaviour.For reference, see #2596.
I totally agree with every word of @alex-pravdin-sn. It’s very important for the community to be able to use unit testing in as much software as we can. And we kindly request from php-unit to support us.