6

我有一个这样的构造:

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。对于临时覆盖内置函数很有用。

4

2 回答 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@codeCoverageIgnoreEndto ,可用于从覆盖分析中排除类、方法或代码部分。

于 2012-12-22T18:51:41.130 回答
1

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

看这个

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

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

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

于 2012-12-22T19:22:50.660 回答