PHP单元测试,带模拟的受保护方法
Posted
技术标签:
【中文标题】PHP单元测试,带模拟的受保护方法【英文标题】:Php unit testing, protected method with mocking 【发布时间】:2013-10-10 02:19:50 【问题描述】:我是 TDD 新手。我被困在一些单元测试中...请看一下我的代码...提前谢谢...
class Parser
protected function _checkCurlExistence()
// Unable to to mock function_exists, thats why fallback with this method
return function_exists('curl_version');
public function checkCurlExtension()
// I want to test 2 situations from this method...
// 1. if curl extension exists
// 2. or when curl extension does not exists...throw error
if($this->_checkCurlExistence() === false)
try
throw new CurlException(); //Some curl error handler exception class
catch(CurlException $error)
exit($error->getCurlExtensionError());
return true;
想测试:
class ParserTest
/**
* @expectedException CurlException
*/
public function testCheckCurlExtensionDoesNotExists()
//Some testing code with mocking...
public function testCheckCurlExtensionExists()
//Some testing code with mocking..and assertion
我的问题/请求:
请您填写这些测试。我永远被困在这上面……无法继续我的 TDD 之旅。
一些步骤(您可以跳过这些行):
我已尽力自己解决此问题,但无法解决。有些步骤是..
我尝试了 phpunit 的原生 mockery、padraic/mockery (git)、codeception/aspect-mock (git) 来模拟 _checkCurlExistence() 两种情况的方法...我不确定我是否做得对...这就是为什么,不发布那些代码...
我尝试了 Reflection Api,通过 magic method __call()... 将受保护方法动态转换为公共方法以帮助模拟...
我也做了很多谷歌搜索。了解最佳实践是仅测试公共方法。但是我的公共方法依赖于受保护的方法......所以我该如何测试???
【问题讨论】:
我更愿意通过 checkCurlExtension() 对其进行测试,我的意思是如果找不到扩展名,它会抛出异常。在您的测试用例中使用它。 F.e $this->setExpectedException("CurlException");你就完成了。那将是在您删除“exit()”函数之后。只是利用例外来发挥你的优势 如果你想测试一个受保护/私有的方法,你可以用一个特殊的测试类来扩展这个类,公开这些方法? 不应测试受保护/私有方法。 【参考方案1】:找到了一种模拟 php 内置函数的方法 PHPUnit function mocker extension
所以我现在可以轻松测试这 2 个场景。
namespace 'myNameSpace';
class Parser
public function checkCurlExtension()
// I want to test 2 situations from this method...
// 1. if curl extension exists
// 2. or when curl extension does not exists...throw error
if(function_exists('curl_version') === false)
throw new CurlException(); //Some curl error handler exception class
return true;
class ParserTest
private $parser;
/**
* @expectedException CurlException
*/
public function testCheckCurlExtensionDoesNotExists()
$funcMocker = \PHPUnit_Extension_FunctionMocker::start($this, 'myNameSpace')
->mockFunction('function_exists')
->getMock();
$funcMocker->expects($this->any())
->method('function_exists')
->will($this->returnValue(false));
$this->parser->checkCurlExtension();
public function testCheckCurlExtensionExists()
//we can do same here...please remember DRY...
【讨论】:
以上是关于PHP单元测试,带模拟的受保护方法的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 IOS 的 XCTest 单元测试用例中模拟方法(带参数)调用