【问题标题】:Mocking PHP functions - naming conventions模拟 PHP 函数 - 命名约定
【发布时间】:2015-04-29 07:06:02
【问题描述】:

在编写将模拟原生 PHP 函数的 OOP 时,创建方法名称的最佳实践是什么?

示例:一个对象需要使用 file_put_contents(),我想模拟它,所以我认为正确的方法是将 file_put_contents() 包装在一个类方法中。但是命名方法的好方法是什么?我在想也许 wrap_file_put_contents() 但是这样的事情有更好的标准吗?谢谢!

【问题讨论】:

标签: php unit-testing phpunit mockery


【解决方案1】:

不要重命名它们。那将是可怕的。对于您似乎正在尝试测试的功能vfsStream 将允许您在不敲磁盘的情况下进行测试,因此可以进行快速的单元测试,因此您可能不需要对其进行模拟。

对于其他事情,您可以使用 hack 来制作函数的模拟版本,而不会影响您正在测试的代码的易读性,而只是稍微有点可怕。

通过声明一个与要模拟的函数同名的函数,但在使用它的函数/方法的命名空间中,函数的命名空间版本将优先于 PHP 版本使用。

文件 SomeNamespace\MockHeader.php:

namespace SomeNamespace;

$headersSet = [];

class MockHeader {
    static function load();
}

function header($string, $replace = true, $http_response_code = null) {
    global $headersSet;
    $headersSet[] = [
       'string' => $string,
       'replace' => $replace,
       'http_response_code' => $http_response_code
    ];
}

文件 SomeNamespace\TestClass.php:

namespace SomeNamespace;

class TestClass {
    function foo() {
        header("Content-Type: image/jpg");
    }
}

通过在单元测试中调用 SomeNamespace\MockHeader::load() 来加载头文件替换函数,并优先使用 PHP 提供的 \header 函数。

您还可以使用 author of that extension 中描述的 Uopz 以编程方式替换函数,而不是 hackily。但任何一种方法都比重命名 imo 更可取。

【讨论】:

    【解决方案2】:

    我不确定是否已经找到了首选的解决方案,但是我对此感到很开心,所以我想我会出于有趣的目的将这个没有命名空间的版本放入代码宇宙中。

    它将优雅地回退到 SPL 函数,并且它是可扩展的。如果您想在 Std 中设置一些默认值,它们可以轻松嵌套。

    最后,对 get_defined_functions() 输出的某种实例控制可能是有意义的,我不确定重复调用的开销是多少:

    <?php
    
    class Std
    {
        public function __call($name, $args)
        {
            $stdFuncs = &get_defined_functions()['internal'];
            if (in_array($name, $stdFuncs))
            {
                return (method_exists($this, $name))
                    ? call_user_func_array(array($this, $name), $args)
                    : call_user_func_array($name, $args);
            }
            return false;
        }
    
        public static function __callStatic($name, $args)
        {
            $stdFuncs = &get_defined_functions()['internal'];
            if(in_array($name, $stdFuncs))
            {
                return (method_exists(get_called_class(), $name))
                ? call_user_func_array(array(get_called_class(), $name), $args)
                : call_user_func_array($name, $args);
            }
            return false;
        }
    }
    
    class Test extends Std
    {
        public static function strlen($string)
        {
            return trim(strlen($string));
        }
    }
    
    // Test it
    $x = new Test();
    echo $x->strlen("test") . PHP_EOL;
    echo $x->intval("test") . PHP_EOL;
    echo Test::strlen("test") . PHP_EOL;
    echo Test::intval("test") . PHP_EOL;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      相关资源
      最近更新 更多