5

我有一些非常不利于测试的代码(至少可以这么说)需要测试。不幸的是,重构不是一种选择。我必须按原样测试代码,而不能更改它。

为此,我正在考虑拦截函数调用并动态更改它们的功能,以便我可以运行我的测试,因为我需要一些函数和方法来返回已知值,并且我需要其他发出请求、连接到数据库等的函数和方法,停止这样做并返回我需要他们返回的东西。有没有办法做到这一点runkit_method_redefine(),最好不是“实验”并且仍然保持?也许是runkit的替代品?也许更好的方法?

编辑:如果我需要该功能,将使用 PHPUnit 的测试替身和 PHP 5.3.2 的功能来使私有方法可访问。

4

2 回答 2

15

注意: Test-Helper 扩展被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'));
}

它还允许拦截退出语句和实例创建:

对于存根和模拟方法,您只需使用 PHPUnit 的常规模拟框架。看

您还可以将 Mockery 与 PHPUnit 一起使用:

另一种选择是使用http://antecedent.github.io/patchwork

Patchwork 是一个 PHP 库,它可以在运行时重新定义用户定义的函数和方法,松散地复制runkit_function_redefine纯 PHP 5.3 代码中的功能,除其他外,它使您能够用测试替身替换静态和私有方法。

于 2011-05-27T15:30:58.097 回答
2

runkit 扩展是满足您需求的完美解决方案。我多年的个人经验证明了这一点,并在互联网上不同作者撰写的许多演示文稿和文章中进行了描述。

我可以向您保证,runkit_method_redefine 函数以及整个 runkit 扩展不再是实验性的(托管在 php.net 上的文档已过时)。最新的 runkit 扩展可以在http://github.com/zenovich/runkit找到

此致 德米特里·泽诺维奇

于 2012-09-08T21:36:58.483 回答