如何使用PHPUnit测试依赖于特定PHP版本的语句?

6

我有一个类似这样的结构:

class Foo
{
    public function doFoo($value = '')
    {
        if (function_exists('foo'))
        {
            return foo($value);
        }
        // if php version does not support foo()
        // ...
    }
}

如何使用PHPUnit测试这段代码以实现100%的代码覆盖率?如果函数foo的存在取决于安装的PHP版本(在本例中假设该函数存在,否则不可能实现100%的代码覆盖率),有没有一种方法可以在运行时禁用/启用PHP函数?
有任何解决方法吗?
编辑:我已经找到了一个解决方案:高级PHP调试器/PECL扩展提供了一个函数*rename_function*来实现此目的。
bool rename_function ( string $original_name , string $new_name )
将orig_name重命名为new_name在全局函数表中。 有助于临时覆盖内置函数。

你使用的 PHP 版本是什么?有可能是 5.3 吗? - zafarkhaja
我使用的是PHP 5.3.15版本。具体问题是,我已经实现了一个PBKDF2方法来创建密码哈希。现在,我发现在PHP >= 5.5.0版本中存在函数hash_pbkdf2。 - nico
2个回答

3
您可以在测试方法中定义foo()的模拟。做法如下:
<?php
/**
 * Your test method
 */
public function testSomething () {

    // if the function not exists, create a simulation
    if(!function_exists('foo')) {
        function foo() {
            return $aValue;
        }
    }

    // your test code ...
}

这是因为函数可以定义在另一个方法或函数中。虽然它们是在方法中定义的,但它们在全局范围内可用。
不需要使用pecl扩展。此外,它可能会“污染”测试执行环境,并增加不必要的要求。
另外,请注意,PHPUnit从版本3.6开始支持注释@codeCoverageIgnore、@codeCoverageIgnoreStart、@codeCoverageIgnoreEnd,可以用于排除类、方法或代码部分从覆盖率分析中。

1

在 PHP 5.3 及更高版本中,您可以覆盖任何 PHP 函数的行为。

看这个

namespace Test
{
    function function_exists($function)
    {
        return false;
    }

    var_dump(function_exists('var_dump')); // bool(false)
}

这是由于 PHP 的 回退机制 所实现的。简而言之,当它遇到一个函数时,首先检查该函数是否存在于当前命名空间中。如果不存在,则会回退到全局命名空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接