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

时间:2012-12-22 18:48:28

标签: php phpunit code-coverage

我有这样的结构:

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

如果函数foo的存在取决于安装的PHP版本,我如何使用PHPUnit测试此代码以实现100%的代码覆盖率(对于此示例,我假设函数存在,否则代码覆盖率为100%是不可能)。有没有办法在运行时禁用/启用PHP函数?

任何想法如何解决?

修改

我找到了一个解决方案:高级PHP调试器/ PECL扩展为此提供了一个函数* rename_function *。

  

bool rename_function(string $ original_name,string $ new_name)

     
    

在全局函数表中将orig_name重命名为new_name。暂时有用     覆盖内置函数。

  

2 个答案:

答案 0 :(得分: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 :(得分:1)

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

看看这个

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

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

由于PHP fallback mechanism,这是可能的。简而言之,当它遇到一个函数时,它首先检查函数是否存在于当前命名空间中。如果没有,它将回退到全局命名空间。