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
protected
method of a full mock, when all of thepublic
methods 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.