我知道可以使用反射或其他解决方法使用PHPUnit测试私有/受保护的方法。
但是大多数消息来源告诉我,为类内的私有方法编写测试是不最佳实践。
你应该测试这个类就好像它是一个“黑盒子” - 你只是通过比较输入和输出而不管内部机制来测试预期的行为。编写类的测试也应该通过显示缺少代码覆盖率来通知您未使用的私有方法。
当我测试我的类并生成HTML报告时,它会显示测试未涵盖的私有方法,即使它们被调用的行被绝对执行/覆盖。我知道私有方法被执行,因为如果它们不是我班上的断言就不会通过。
这是PHPUnit中的预期行为吗?我是否可以争取100%的覆盖率,同时仅间接测试私人方法?
一些简化的示例代码(在Symfony2中使用RestBundle):
class ApiController extends FOSRestController {
/*
* @REST\View()
* @REST\Get("/api/{codes}")
*/
public function getCodesAction($codes) {
$view = new View();
$view->setHeader('Access-Control-Allow-Origin', '*');
$view->setData(array('type' => 'codes','data' => $this->_stringToArray($codes)));
$view->setFormat('json')->setHeader('Content-Type', 'application/json');
return $this->handleView($view);
}
private function _stringToArray($string){
return explode('+',$string);
}
公共函数显示为“覆盖”,私有函数被间接覆盖,但在PHPUnit报告中显示为红色。
测试:
class ApiControllerTest extends WebTestCase {
public function test_getCodesAction(){
$client = static::createClient();
$client->request('GET', '/api/1+2+3');
$this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent());
}
}
这当然只是一个愚蠢的例子,我也可以在公共函数中包含explode();但我正在编写的控制器包含更多复杂且可重复使用的私有函数,这些函数以更复杂的方式转换数据(但仍然没有副作用)。
答案 0 :(得分:3)
在Phpunit中,您可以使用特殊注释指定涵盖方法,如doc中所述。
您可以这样做:
class ApiControllerTest extends WebTestCase {
/**
* @covers ApiController::getCodesAction
* @covers ApiController::_stringToArray
*/
public function test_getCodesAction(){
$client = static::createClient();
$client->request('GET', '/api/1+2+3');
$this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent());
}
}
希望这个帮助