你能在回调中使用 $this 来获取 phpunit 中模拟类的 protected 属性吗? 或者有其他方法可以实现吗?
$mock = $this->getMock('A', array('foo'));
$mock->expects($this->any())->method('foo')->will(
$this->returnCallback(function() {
return $this->bar;
}));
如果您考虑注入(inject)模拟对象,这可能非常有用。 有时类对其他类具有硬编码依赖性,但它使用理论上可以模拟并创建模拟对象而不是硬编码对象的方法来创建它。请看另一个例子。
class A {
protected $bar = "bar";
public function foo () {
$b = new B();
return $b->fizz($this->bar);
}
}
class B {
public function fizz ($buzz) {
return $buzz;
}
}
但是假设类 B 做了一些坏事,我想用 mock 替换它。
$mockB = $this->getMock('B');
// (...) - and probably mock other things
$mockA = $this->getMock('A', array('foo'));
$mockA->expects($this->any())->method('foo')->will(
$this->returnCallback(function() use ($mockB) {
return $mockB->fizz($this->bar);
}));
这是可以实现的吗?
当然没有任何意外,目前,如果我像上面那样做,我会得到错误:
PHP Fatal error: Using $this when not in object context in (...)
使用 use
关键字我可以从父作用域继承 $mockA:
$mockB = $this->getMock('B');
// (...) - and probably mock other things
$mockA = $this->getMock('A', array('foo'));
$mockA->expects($this->any())->method('foo')->will(
$this->returnCallback(function() use ($mockA, $mockB) {
return $mockB->fizz($mockA->bar);
}));
但是通过这种方式我将尝试以公共(public)方式访问 bar 并且我将得到:
PHP Fatal error: Cannot access protected property (...)
最佳答案
正如其他答案所指出的,自 PHP 5.4 起,$this
可用于闭包。一个鲜为人知的事实是,您可以将闭包绑定(bind)到任意对象,实际上可以像那样访问它们的私有(private)属性。你需要的方法是bindTo()
,它返回一个具有不同上下文的新闭包。
$cb = function() {
return $this->bar;
};
$cb = $cb->bindTo($mockA);
或者更准确地说,你的例子看起来像这样:
$mockB = $this->getMock('B');
// (...) - and probably mock other things
$mockA = $this->getMock('A', array('foo'));
$fooCallback = function() use (&$mockB) {
return $mockB->fizz($this->bar);
};
$mockA->expects($this->any())->method('foo')->will(
$this->returnCallback($fooCallback->bindTo($mockA)));
关于php - 您可以在回调中使用 $this 来获取 phpunit 中模拟类的 protected 属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14792929/