获取简单 '} 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
之前的右括号 }
在技术上是可以到达的,但是您没有覆盖它的测试。
我无法让 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
之前的右括号 }
在技术上是可以到达的,但是您没有覆盖它的测试。