Я пытаюсь реализовать тип макета для объектов 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"
Задача ещё не решена.
Других решений пока нет …