如何在 PHP 中存根这个函数

How do I stub this function in PHP

我有以下class我想测试:

<?php

namespace Freya\Component\PageBuilder\FieldHandler;

use Freya\Component\PageBuilder\FieldHandler\IFieldHandler;

/**
 * Used to get a set of non empty, false or null fields.
 *
 * The core purpose is to use this class to determine that A) Advanced Custom Fields is installed
 * and B) that we get back a set of fields for a child page.
 *
 * The cavete here is that this class requires you to have child pages that then have Custom Fields that
 * you want to display on each of those pages. getting other page information such as content, title, featured image
 * and other meta boxes is left ot the end developer.
 *
 * @see Freya\Component\PageBuilder\FieldHandler\IFieldHandler
 */
class FieldHandler implements IFieldHandler {

    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function checkForAFC() {
        return function_exists("register_field_group");
    }

    /**
     * {@inheritdoc}
     *
     * @param $childPageID - the id of the child page who may or may not have custom fields.
     * @return mixed - Null or Array
     */
    public function getFields($childPageId) {
        $fieldsForThisPage = get_fields($childPageId);

        if (is_array($fieldsForThisPage)) {
            foreach ($fieldsForThisPage as $key => $value) {
                if ($value === "" || $value === false || $value === null) {
                    unset($fieldsForThisPage[$key]);
                }
            }

            return $fieldsForThisPage;
        }

        return null;
    }
}

我可以测试所有这些,但我想做的一件事是存根 get_fields() 函数,表示您将 return 这种类型的数组,然后将如何使用其余的函数使用它,在本例中循环遍历它。

我在 php 中不知道如何做的部分是存根正在调用的函数,然后说你将 return x.

那么我该如何存根 get_fields

您可以在全局命名空间中定义此类函数。看看下面的例子:

namespace {
    function getFields($pageId) {
        return array($pageId);
    }
}

namespace MyNamespace {
    class MyClass
    {
        public function foo(){
            var_dump(getFields(5));
        }
    }

    $obj = new MyClass();
    $obj->foo();
}

这是输出:

array(1) {
  [0]=>
  int(5)
}

唯一的问题是这个函数将一直存在到脚本结束。要解决此问题,您可以将 tearDown 方法与 runkit 库一起使用:

http://php.net/manual/en/function.runkit-function-remove.php

允许您删除用户定义的函数。 不幸的是,这个库在 Windows 上不存在,因此您将无法删除该定义,并且可以考虑单独进行 运行 测试。

编辑: 你也可以考虑使用这个库(它也依赖于 runkit): https://github.com/tcz/phpunit-mockfunction

你可以在这里使用 非限定函数名 get_fields() 的技巧。由于你没有使用 fully qualified 函数名 \get_fields() PHP 将首先尝试在当前命名空间中查找函数,然后回退到全局函数名字.

合格和不合格的定义见:http://php.net/manual/en/language.namespaces.basics.php(类似于绝对文件名和相对文件名)

所以你要做的就是在 class 的命名空间中定义函数以及你的测试用例,如下所示:

namespace Freya\Component\PageBuilder\FieldHandler;

function get_fields()
{
    return ['X'];
}

class FieldHandlerTest extends \PHPUnit_Test_Case
{
    ...
}

补充说明: