Reputation: 12869
I have an abstract class Exception
in custom namespace which has no abstract methods. All methods are shown as covered by its tests (mocked in a standard way). The reason to make it abstract is unimportant.
Then I have about 10 classes that extend Exception
but don't add or override any methods, properties, constants, etc. It is obvious that all of them should be covered too, but they are shown as not fully covered. I read the docs and googled for a while but didn't find the answer.
While annotating with @codeCoverageIgnore
is a solution I want to find out why it happens this way rather then get 100% coverage.
UPD: sources.
------------- abstract class ----------
namespace Jade\Core\Base;
abstract class Exception extends \Exception {
/**
* Additional info for exception
* @var array|null
*/
protected $info;
public function __construct($message, array $info = null, $code = 0, \Exception $previous = null) {
parent::__construct($message, $code, $previous);
$this->info = $info;
}
/**
* Get the Exception additional info
* @return mixed
*/
public function getInfo() {
return $this->info;
}
}
------------- Tests for abstract class ----------
class ExceptionTest extends \PHPUnit_Framework_TestCase {
/**
* @covers \Jade\Core\Base\Exception
*
* @group public
*/
public function testGetInfo() {
$info = array('info' => 'test');
$stub = $this->getMockForAbstractClass('\Jade\Core\Base\Exception', array('message', $info));
$this->assertEquals($info, $stub->getInfo());
}
/**
* @covers \Jade\Core\Base\Exception
*
* @group public
*/
public function testConstructWithDefaultInfo() {
$stub = $this->getMockForAbstractClass('\Jade\Core\Base\Exception', array('message'));
$this->assertEmpty($stub->getInfo());
}
}
------------- class that extends abstract class ----------
namespace Jade\Core\Exceptions;
class Dict extends \Jade\Core\Base\Exception {
}
Update
Renaming \Jade\Core\Base\Exception
to avoid possible collision with \Exception didn't help (i tried \Jade\Core\Base\Ixception
).
Making Exception class a regular class, not abstract also didn't help.
Upvotes: 2
Views: 1843
Reputation: 12869
The problem was entirely in class autoloading. To get work i had to manually include files with classes sources in bootstrap file.
Upvotes: 1
Reputation: 36562
The class declaration is viewed as executable code by Xdebug, and you must use that class ('\Jade\Core\Exceptions\Dict' above) in order to show it as covered. Since this class is designed to be instantiated, you must create at least one object using it.
As posted your tests are not instantiating Dict
, and therefore Dict
is in fact not covered. You need to change your mock object creation to use Dict
instead of \Jade\Core\Base\Exception
.
$stub = $this->getMockForAbstractClass('\Jade\Core\Exceptions\Dict', ...);
Note
PHPUnit and PHP_CodeCoverage merely interpret the data supplied by Xdebug which has a few corner cases where non-executable code is treated as executable including close braces on if
and else
blocks, the class declaration not counted as executed even when you instantiate it, and stating that non-existent lines before and after the file contents are executed. If you can create a minimal test case to demonstrate a true problem, post it to Xdebug's issue tracker.
Upvotes: 1