我有一些非常不友好的测试代码(至少可以说是我需要测试的)。不幸的是,重构不是一种选择。我必须按原样测试代码,而不必更改代码。
要做到这一点,我正在考虑拦截函数调用并动态更改它们的作用,以便我可以运行我的测试,因为我需要一些函数和方法来返回已知值,我需要其他人发出请求,连接到数据库等,停止这样做并返回我需要它们返回的内容。有没有办法在没有runkit_method_redefine()
的情况下做到这一点,最好不是“实验”并仍然保持?也许是runkit的替代品?也许是更好的方式?
编辑:如果我需要这个功能,将使用PHPUnit的测试双打和PHP 5.3.2的功能来使私有方法可访问。
答案 0 :(得分:15)
注意: the Test-Helper extension is superseded https://github.com/krakjoe/uopz
PHPUnit的Test Helper扩展(PECL)允许redefiniton/intercepting/stubbing/mocking of hardcoded dependencies使用您自己的实现:
protected function setUp()
{
$this->getMock(
'Bar', /* name of class to mock */
array('doSomethingElse'), /* list of methods to mock */
array(), /* constructor arguments */
'BarMock' /* name for mocked class */
);
set_new_overload(array($this, 'newCallback'));
}
它还允许拦截exit语句和实例创建:
对于存根和模拟方法,您只需使用PHPUnit的常规模拟框架。见
您还可以将Mockery与PHPUnit一起使用:
另一种选择是使用http://antecedent.github.io/patchwork
Patchwork是一个PHP库,可以在运行时重新定义用户定义的函数和方法,在纯PHP 5.3代码中松散地复制功能
runkit_function_redefine
,除此之外,还可以替换静态和私有方法与测试双打。
答案 1 :(得分:2)
runkit扩展是满足您需求的完美解决方案。多年的个人经验证明了这一点,并在互联网上不同作者撰写的许多演讲和文章中进行了描述。
我可以向您保证runkit_method_redefine函数以及整个runkit扩展不再是实验性的(在php.net上托管的文档已经过时)。 可以在http://github.com/zenovich/runkit
上找到最新的runkit扩展此致 德米特里·泽诺维奇