【问题标题】:PHPUnit code coverage for class that extends abstract class扩展抽象类的类的 PHPUnit 代码覆盖率
【发布时间】:2012-08-17 22:02:07
【问题描述】:

我在自定义命名空间中有一个抽象类Exception,它没有抽象方法。所有方法都显示在其测试中(以标准方式模拟)。使其抽象的原因并不重要。

然后我有大约 10 个类扩展 Exception 但不添加或覆盖任何方法、属性、常量等。很明显,它们都应该被覆盖,但它们显示为未完全覆盖.我阅读了文档并搜索了一段时间,但没有找到答案。

  • PHP_CodeCoverage 1.1.3
  • PHPUnit 3.6.12
  • PHP 5.4.4
  • Xdebug 2.2.1-5.4-vc9

虽然使用 @codeCoverageIgnore 注释是一种解决方案,但我想找出为什么会这样,而不是获得 100% 的覆盖率。

UPD:来源。

----------抽象类----------

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;
    }
}

------------- 抽象类测试 ----------

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());
    }
}

---------- 扩展抽象类的类 ----------

namespace Jade\Core\Exceptions;


class Dict extends \Jade\Core\Base\Exception {
}

更新

重命名\Jade\Core\Base\Exception 以避免可能与\Exception 发生冲突并没有帮助(我尝试了\Jade\Core\Base\Ixception)。

使异常类成为常规类,而不是抽象类也没有帮助。

【问题讨论】:

  • 您能否发布一个示例,说明哪些行显示为未覆盖?是类声明还是大括号?
  • 感谢编辑,我添加了源代码和 CodeCoverage 输出。
  • 是的,这是我的错。我尝试了声明以使其按预期工作并忘记撤消更改。我修复了它,覆盖问题没有解决。

标签: php phpunit abstract-class code-coverage xdebug


【解决方案1】:

Xdebug 将类声明视为可执行代码,您必须使用该类(上面的'\Jade\Core\Exceptions\Dict')才能将其显示为已覆盖。由于此类被设计为实例化,因此您必须使用它创建至少一个对象。

正如发布的那样,您的测试没有实例化Dict,因此Dict 实际上没有被覆盖。您需要更改您的模拟对象创建以使用Dict 而不是\Jade\Core\Base\Exception

$stub = $this->getMockForAbstractClass('\Jade\Core\Exceptions\Dict', ...);

注意

PHPUnit 和 PHP_CodeCoverage 仅解释 Xdebug 提供的数据,其中有一些极端情况,其中不可执行代码被视为可执行代码,包括 ifelse 块上的右括号,即使在你实例化它,并声明文件内容执行前后不存在的行。如果您可以创建一个最小的测试用例来演示一个真正的问题,请将其发布到Xdebug's issue tracker

【讨论】:

  • \Jade\Core\Exceptions\Dict 在我的 \Jade\Core\Base\Dict 类内部抛出。我还更新了我的问题,指出将\Jade\Core\Base\Exception 设为常规(非抽象)类并没有帮助。实际上,正如我们在示例中看到的那样,\Jade\Core\Exceptions\Dict 扩展了\Jade\Core\Base\Exception,但没有添加新功能(方法、道具),所以我认为它也应该基于\Jade\Core\Base\Exception 的测试来涵盖。顺便说一句,当使用命名空间时,我们应该给出完整的类名,命名空间$stub = $this->getMockForAbstractClass('\Jade\Core\Exceptions\Dict', ...);
  • 按照您的建议,我将尝试创建不太复杂的示例来演示问题。
  • @pinepain - 字典 JCBD 抛出异常 JCED,但您的测试创建了一个模拟 exception——而不是字典。我仍然看不到您的测试在字典中调用代码的位置会导致抛出异常。您的测试甚至声明它们涵盖了该基本异常 - 而不是孩子。您可能对涵盖异常的字典进行了测试,但我想澄清一下,上面的帖子不包含涵盖子异常的代码。
  • 所以,问题是JCED 显示为未覆盖。是的,它没有被覆盖,因为它没有额外的功能。我想如果它的父 JCBE 被它自己的测试完全覆盖(有或没有模拟,没关系,恕我直言)。也许我在这里错过了一些观点?
  • 看我的重写,但长话短说你必须使用一个类来覆盖它。
【解决方案2】:

问题完全在于类自动加载。为了开始工作,我必须在引导文件中手动包含带有类源的文件。

【讨论】:

  • 您能说得更具体些吗?也许是一些例子?我遇到了同样的问题。
  • 我猜你现在是一个人了,我几乎不记得是什么问题和解决方案了,对不起。
猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 2015-03-17
  • 2012-08-04
  • 2012-01-18
  • 2018-05-29
  • 2017-02-22
相关资源
最近更新 更多