【问题标题】:Getting PHPUNit code coverage of simple '} else {' line获取简单 '} else {' 行的 PHPUNit 代码覆盖率
【发布时间】:2017-05-31 01:26:19
【问题描述】:

我无法让 PHPUnit 的代码覆盖工具将这个 else 语句标记为已覆盖,即使它必须被覆盖,或者无法覆盖以下行。在同一类的其他地方,仅包含 } else { 的另一行被正确标记为已覆盖。

    if (is_string($externalId) && $externalId != '') {
        $sitesIds[] = $externalId;
    } else if ($regionName != null && $regionName != '') {
        $sitesIds = $this->sitesService->getSites($regionName);
        if (!is_array($sitesIds) || count($sitesIds) == 0) {
            throw new \Exception(self::NO_MATCHING_REGION, '404');
        }
    } else {
        throw new \Exception(self::BAD_REQUEST.'. Should specify station or region', '400');
    }

【问题讨论】:

  • 我知道在测试中让一行变成绿色并不能改进代码,但我的强迫症迫使我尽可能地覆盖最后一行:-)
  • 是否移动 else { 以分隔行更改内容?
  • @Furgas No. } 标记为未覆盖,而 else { 为白色,表示不打算覆盖/测试

标签: php phpunit code-coverage


【解决方案1】:

由于else 实际上并没有做任何事情(它可以被认为只是一个标签)它不会被覆盖。

您的问题是您没有测试,其中(is_string($externalId) && $externalId != '')false($regionName != null && $regionName != '')true(!is_array($sitesIds) || count($sitesIds) == 0)false。 (您可能希望更具体地使用不完全等于!== 而不是不等于!=($externalId !== '')($regionName !== null && $regionName !== '')

如果您可以让$sitesIds = $this->sitesService->getSites($regionName); 返回一个包含至少一个元素的数组,您的红线将被覆盖并变为绿色。

红线告诉您else 之前的右大括号} 在技术上是可以访问的,但您没有涵盖它的测试。

【讨论】:

  • 做到了。之前的测试只到了throw
【解决方案2】:

源代码稍作修改:

class A
{
    const NO_MATCHING_REGION = 1;
    const BAD_REQUEST        = 2;

    private $sitesService = ['a' => ['AA'], 'b'=>12];

    public function a($externalId, $regionName)
    {
        $sitesIds = [];
        if (is_string($externalId) && $externalId != '') {
            $sitesIds[] = $externalId;
        } else {
            if ($regionName != null && $regionName != '') {
                $sitesIds = $this->sitesService[$regionName];
                if (!is_array($sitesIds) || count($sitesIds) == 0) {
                    throw new \Exception(self::NO_MATCHING_REGION, '404');
                }
            } else {
                throw new \Exception(self::BAD_REQUEST.'. Should specify station or region', '400');
            }
        }
        return $sitesIds;
    }
}

测试

class ATest extends \PHPUnit_Framework_TestCase
{

    /**
     * @dataProvider data
     */
    public function testOk($id, $reg, $res)
    {
        $a = new A;
        $r = $a->a($id, $reg);
        $this->assertEquals($res, $r);
    }

    public function data()
    {
        return [
            ['a', 1, ['a']],
            [1,'a', ['AA']]
        ];
    }

    /**
     * @dataProvider error
     * @expectedException \Exception
     */
    public function testNotOK($id, $reg)
    {
        $a = new A;
        $a->a($id, $reg);
    }

    public function error()
    {
        return [
            [1,'b'],
            [1,null]
        ];
    }
}

覆盖else 行:

PHP 5.6.15-1+deb.sury.org~trusty+1

PHPUnit 4.8.21

【讨论】:

    猜你喜欢
    • 2012-05-04
    • 2012-01-18
    • 2012-01-14
    • 2014-06-27
    • 2012-08-04
    • 2018-05-29
    • 2011-05-27
    • 2017-02-22
    • 2021-10-05
    相关资源
    最近更新 更多