一个函数存根-不涉及类-php

一个函数存根-不涉及类-php,php,wordpress,phpunit,Php,Wordpress,Phpunit,您看到的第一个函数是我想要存根的,根据phpunit文档,我将存根该类,然后是该方法以及该方法将返回的内容。然后我可以调用该类,并期望该方法被调用一次 如何使用以下函数-我在一个类中使用了该函数: public function checked($value, $option, $key) { $options = get_option($option); if (isset($options[$key]) && $options[$key] == $value

您看到的第一个函数是我想要存根的,根据phpunit文档,我将存根该类,然后是该方法以及该方法将返回的内容。然后我可以调用该类,并期望该方法被调用一次

如何使用以下函数-我在一个类中使用了该函数:

public function checked($value, $option, $key) {
    $options = get_option($option);

    if (isset($options[$key]) && $options[$key] == $value) {
        return $this->checked =  'checked';
    }
}

您可以看到我调用了
get_option()
我需要存根该函数以返回特定数组,在php中如何才能做到这一点?

您不能存根函数

它与类一起工作的原因是,PHPUnit动态创建PHP源代码,声明一个扩展原始类的模拟类,覆盖要存根的函数。它不能与声明为final的函数一起工作

但是,有一种情况甚至允许使用存根函数:使用名称空间

调用函数将首先尝试在当前命名空间中调用该名称的函数。如果没有,则使用全局命名空间。这样,即使在名称空间中,也可以直接调用PHP函数,如
strpos()
,而不必担心在它们前面加反斜杠

现在以此为例:

namespace Stub;

function strpos($foo, $bar) {
    return "The return value is stubbed";
}

# This will not call the PHP function
echo strpos("string", "i");
因此,如果您将测试放在一个名称空间中,并在同一名称空间中定义函数,那么对该函数的调用将被拦截

现在唯一的麻烦是,您要测试的类中的代码必须在同一命名空间中(或者反过来说,测试和存根函数必须在您要测试的类的命名空间中)——如果不是,您就不能将函数添加到该命名空间中。此外,您只能添加一次函数-您应该知道如何使函数像模拟一样运行,可能有一个全局变量包含用于检查调用和提供返回值的已配置模拟对象


然而,这一切迟早会变得一团糟。全局函数不能在PHP中以干净的方式进行模拟/存根。

可以使用


看看,它允许用另一个包含自定义逻辑的函数临时替换一个函数。

事实上,WordPress经常使用函数,它们很难以干净的方式存根

但是,您可以使用如下方法包装函数:

public function get_option($option) {
    return get_option($option);
}

public function checked($value, $option, $key) {
    $options = $this->get_option($option);

    if (isset($options[$key]) && $options[$key] == $value) {
        return $this->checked =  'checked';
    }
}
现在,您可以轻松地模拟get_选项方法