在 PHPUnit 中,如何模拟不属于类的函数?

Rad*_*zea 4 php phpunit mocking

我目前正在处理的项目包含面向对象和过程 PHP 代码的混合。所以我有这样的事情:

function doStuff($value)
{
    $x = $value + 1;

    return $x;
}

class MyClass
{
    private $field;

    public function setMyValue($amount)
    {
        $this->field = doStuff($amount) + doStuff(2 * $amount);
    }
}
Run Code Online (Sandbox Code Playgroud)

这些依赖项有一些,但很少(您可以用一只手数数它们)。但是,我需要为这些类编写单元测试(使用 PHPUnit),我不知道如何模拟来自程序端的函数(在本例中doStuff)。据我所知,PHPUnit 中的模拟功能仅适用于类。

我会在没有任何模拟的情况下完成它,但问题是其中一些函数会执行一些 IO 操作;我认为不以某种方式嘲笑他们不是一个好主意。

我该如何解决这个问题?

Mar*_*sch 5

当您从命名空间调用函数(在全局命名空间中定义)并始终不加限定地调用它们时,您可以利用PHP 的命名空间回退策略

如果命名空间函数 [...] 不存在,PHP 将回退到全局函数 [...]。

这允许您通过在调用者的命名空间中提供函数来创建模拟。

为了让您的生活特别轻松,我将其打包到可与 PHPUnit 一起使用的库php-mock-phpunit中:

namespace foo;

use phpmock\phpunit\PHPMock;

class BuiltinTest extends \PHPUnit_Framework_TestCase
{

    use PHPMock;

    public function testTime()
    {
        $time = $this->getFunctionMock(__NAMESPACE__, "time");
        $time->expects($this->once())->willReturn(3);

        $this->assertEquals(3, time());
    }
}
Run Code Online (Sandbox Code Playgroud)