我有一些非常不友好的代码(至少可以说(需要测试。不幸的是,重构不是一种选择。我必须按原样测试代码,而无法更改它。
为此,我正在考虑拦截函数调用并动态更改它们的作用,以便我可以运行我的测试,因为我需要一些函数和方法来返回已知值,我需要其他发出请求、连接到数据库等的函数和方法来停止这样做并返回我需要它们返回的内容。有没有办法在没有runkit_method_redefine()
的情况下做到这一点,最好不是"实验性的"并且仍然保持?也许是 runkit 的替代品?也许有更好的方法?
编辑:如果我需要该功能,将使用 PHPUnit 的测试替身和 PHP 5.3.2 的功能来使私有方法可访问。
注意:测试帮助程序扩展被 https://github.com/krakjoe/uopz 取代
PHPUnit 的测试助手扩展 (PECL( 允许使用您自己的实现重新定义/拦截/存根/模拟硬编码依赖项:
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'));
}
它还允许拦截退出语句和实例创建:
- https://github.com/sebastianbergmann/php-test-helpers
对于存根和模拟方法,您只需使用 PHPUnit 的常规模拟框架即可。看
- http://www.phpunit.de/manual/current/en/test-doubles.html
您还可以将 Mockery 与 PHPUnit 一起使用:
- https://github.com/padraic/mockery
另一种选择是使用 http://antecedent.github.io/patchwork
Patchwork 是一个 PHP 库,它可以在运行时重新定义用户定义的函数和方法,松散地复制纯 PHP 5.3 代码中
runkit_function_redefine
的功能,除其他外,它使您能够用测试替身替换静态和私有方法。
runkit 扩展是满足您需求的完美解决方案。我多年的个人经验证明了这一点,并在互联网上不同作者撰写的许多演示文稿和文章中进行了描述。
我可以向您保证,runkit_method_redefine函数以及整个 runkit 扩展不再是实验性的(php.net 上托管的文档已经过时(。最新的 runkit 扩展可以在 http://github.com/zenovich/runkit 上找到
真诚地德米特里·泽诺维奇