使用默认属性创建模拟对象

Mik*_*e B 11 php phpunit

我需要使用默认的属性集创建一个模拟对象,以便在实例化时可以在代码库中使用elseware.

$mock = $this->getMock('MyClass', array(), array(), 'MyClass_Mock');
$mock->prop = 'foobar';

$myclassMock = new get_class($mock);
var_dump($myclassMock->prop); // NULL
// How can I make this dump 'foobar' ?
Run Code Online (Sandbox Code Playgroud)

我正在测试确定,定位和实例化这些类的框架的一部分,因此注入模拟对象会破坏测试的目的.

我不需要模拟任何方法..只需动态创建一个模拟类,如下所示:

class MyClass_Mock extends MyClass {
  public $prop = 'foobar';
}
Run Code Online (Sandbox Code Playgroud)

编辑:简化示例

Lei*_*igh 4

您对使用反射感觉如何?

$r = new ReflectionClass('MyClass');

$props = $r->getDefaultProperties();

$mock = new stdClass;

foreach ($props as $prop => $value) {
    $mock->$prop = $value;
}
Run Code Online (Sandbox Code Playgroud)

我自己并没有大量使用Reflection,仅用于基本的内省。我不确定您是否能够使用它完全模仿可见性等,但我不明白如果您继续沿着写入字符串和evaling 的路线前进,为什么不呢?

编辑:

出于好奇而扫描反射函数,如果您在字符串中动态构建类,那么完全有可能使用虚拟方法完全模仿该类,在适当的情况下实现完整的可见性约束、常量和静态元素eval

然而,当涉及到正确的数据类型时,真正完全支持每种可能性似乎是一个完整的任务(例如,您需要代码从数组重建数组构造函数)

如果你走这条路,祝你好运,它需要比我现在愿意花的更多的脑力:)

这里有一些代码,您可以对常量执行相同的操作,并以类似的方式创建空方法。

class Test
{
    private static $privates = 'priv';
    protected $protected = 'prot';
    public $public = 'pub';
}

$r = new ReflectionClass('Test');

$props = $r->getDefaultProperties();

$mock = 'class MockTest {';

foreach ($props as $prop => $value) {
    $rProp = $r->getProperty($prop);


    if ($rProp->isPrivate()) {
        $mock .= 'private ';
    }
    elseif ($rProp->isProtected()) {
        $mock .= 'protected ';
    }
    elseif ($rProp->isPublic()) {
        $mock .= 'public ';
    }

    if ($rProp->isStatic()) {
        $mock .= 'static ';
    }

    $mock .= "$$prop = ";

    switch (gettype($value)) {
        case "boolean":
        case "integer":
        case "double":
            $mock .= $value;
            break;
        case "string":
            $mock .= "'$value'";
            break;
/*
"array"
"object"
"resource"
*/
    case "NULL":
            $mock .= 'null';
            break;
    }

    $mock .= ';';
}

$mock .= '}';

eval($mock);

var_dump(new MockTest);
Run Code Online (Sandbox Code Playgroud)

  • 如果可以的话,我会给你两次投票。感谢您付出的努力..到目前为止我还没有尝试过反射路线,但听起来很有趣。我会尝试一下您的一些建议,看看效果如何:) (2认同)