我正在尝试为PHP对象实现一种模拟。通过使用魔术方法(__call
,__get
)来拦截方法调用和成员访问,我很确定我可以隐藏闭包并替换它们,以便存根方法。然而,有一件事我无法绕过头脑,就是如何愚弄类型暗示相信我的物体属于模拟类型。
可以这样做吗?使用ReflectionClass
是可以的,但我宁愿不在PHPUnit中使用。
考虑以下(仓促编写的)代码:
class Thing {};
class ThingCollection {
private $things;
public function __construct () { $this->things = array(); }
public function addThing ( Thing $thing ) { $this->things[] = $thing; }
};
class Mock {
private $__obj;
private $__stubbedMethods;
public function __construct ( $obj, $args ) {
$this->__obj = new $obj(...$args);
}
public function __call ( $name, $args ) {
if ( isset( $this->__stubbedMethods ) )
return call_user_func_array( $this->stubbedMethods, $args );
return call_user_func( $this->__obj->{$name}, $args );
}
public function stub ( $name, callable $method ) {
$this->__stubbedMethods[$name] = $method;
}
};
$mock = new Mock( 'Thing', array() );
$collection = new ThingCollection();
$collection->addThing( $mock ); // error: "must be an instance of Thing"