我有一个构建层次结构的类(要扩展)。创建新对象时,它将构造函数中的父对象作为参数。然后,正在创建的对象的构造函数让父级知道它现在是它的子级。简化如下:
abstract class Hierarchy {
private $children;
public function __construct(Hierarchy $parent = null) {
if ($parent) { $parent->addChild($this); }
}
protected function addChild(Hierarchy $child) {
$this->children[] = $child;
}
}
现在要测试一下,我有以下代码:
$parent = $this->getMockBuilder('Hierarchy')
->setMethods(['addChild'])
->getMockForAbstractClass();
$parent->expects($this->once())
->method('addChild');
$child = $this->getMockBuilder('Hierarchy')
->setConstructorArgs([$parent])
->getMockForAbstractClass();
我希望能够测试的是,正在创建的$ child实例被传递给$ parent addChild,所以我真的想要这个:
$parent->expects($this->once())
->method('addChild')
->with($this->getMockBuilder('Hierarchy')
->setConstructorArgs([$parent])
->getMockForAbstractClass());
但这不起作用。我得到“模拟方法不存在”。 (这有点像鸡肉和鸡蛋 - 在创建之前检查实例但需要使用实例来检查......)
那么无论如何都要从期望中获取一个延迟对象并检查它是否在事后被某个参数调用了?
有点像这样:
$parent = $this->getMockBuilder('Hierarchy')
->setMethods(['addChild'])
->getMockForAbstractClass();
$deferred = $parent->expects($this->once())
->method('addChild');
$child = $this->getMockBuilder('Hierarchy')
->setConstructorArgs([$parent])
->getMockForAbstractClass();
$deferred->wasCalledWith($child);
答案 0 :(得分:2)
这会有用吗?
$parent = $this->getMockBuilder('Hierarchy')
->setMethods(['addChild'])
->getMockForAbstractClass();
$child = $this->getMockBuilder('Hierarchy')
->disableOriginalConstructor()
->setMethods(['__construct'])
->getMockForAbstractClass();
$parent->expects($this->once())
->method('addChild')
->with($child);
$child->__construct($parent);