在编写将模拟本机PHP函数的OOP时创建方法名称的最佳实践是什么?
示例:一个对象需要使用file_put_contents(),我想模仿它,所以我认为正确的方法是在类方法中包装file_put_contents()。但是,命名这些方法的好方法是什么?我想也许是 wrap_file_put_contents(),但这样的事情有更好的标准吗?感谢名单!
答案 0 :(得分:1)
不要重命名它们。那太可怕了。对于您似乎正在尝试测试的功能vfsStream将允许您测试没有击中磁盘,因此进行快速单元测试,因此您可能不需要嘲笑它。
对于其他事情,您可以使用hack来制作该函数的模拟版本,而不会影响您正在测试的代码的易读性,而只是非常可怕。
通过声明一个与要模拟的函数同名的函数,但是在使用它的函数/方法的命名空间中,函数的命名空间版本将优先于PHP版本使用。
File 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
];
}
File 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。但是任何一种方法都比重命名事物更好。
答案 1 :(得分:0)
我不确定是否已经找到了一个首选的解决方案,但是我对此感到非常有趣,所以我想我会把这个没有命名空间的版本放到代码cosmos中以达到有趣的目的。
它将优雅地回归到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;