获取简单 '} else {' 行的 PHPUNit 代码覆盖率

Getting PHPUNit code coverage of simple '} else {' line

我无法让 PHPUnit 的代码覆盖率工具将此 else 语句标记为已覆盖,即使它必须被覆盖或无法覆盖以下行。在同一个 class 的其他地方,仅包含 } 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');
    }

来源略有修改:

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

PHP单元 4.8.21

由于 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);到return一个至少有一个元素的数组,你的红线就会被覆盖变成绿色。

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