Kam*_*zic 7 php phpunit unit-testing mocking
你可以在回调中使用$ this来获取phpunit中被模拟类的受保护属性吗?或者还有其他方法可以实现吗?
$mock = $this->getMock('A', array('foo'));
$mock->expects($this->any())->method('foo')->will(
$this->returnCallback(function() {
return $this->bar;
}));
Run Code Online (Sandbox Code Playgroud)
如果考虑注入模拟对象,这可能非常有用.有时类对其他类具有硬编码依赖性,但它使用方法创建它,理论上可以模拟和创建模拟对象而不是硬编码对象.请看另一个例子.
class A {
protected $bar = "bar";
public function foo () {
$b = new B();
return $b->fizz($this->bar);
}
}
class B {
public function fizz ($buzz) {
return $buzz;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,让我们说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);
}));
Run Code Online (Sandbox Code Playgroud)
这在某种程度上是可以实现的吗?
当然没有任何意外,目前,如果我这样做,那么我得到错误:
PHP Fatal error: Using $this when not in object context in (...)
Run Code Online (Sandbox Code Playgroud)
使用use
关键字I可以从父作用域继承$ 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);
}));
Run Code Online (Sandbox Code Playgroud)
但这样我会尝试访问公共酒吧,我会得到:
PHP Fatal error: Cannot access protected property (...)
Run Code Online (Sandbox Code Playgroud)
正如其他答案所指出的那样,$this
可以在PHP 5.4中使用.一个鲜为人知的事实是,您可以将闭包绑定到任意对象,实际上可以像这样访问它们的私有属性.您需要的方法是bindTo()
返回具有不同上下文的新闭包.
$cb = function() {
return $this->bar;
};
$cb = $cb->bindTo($mockA);
Run Code Online (Sandbox Code Playgroud)
或者更确切地说,您的示例看起来像这样:
$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)));
Run Code Online (Sandbox Code Playgroud)
从 php 5.4 开始,您可以$this
在闭包中使用,但您必须从包含这些受保护属性的对象返回此回调:
class A {
protected $bar = "bar";
public function foo () {
$b = new B();
return $b->fizz($this->bar);
}
public function getCallback(B $b) {
return function() use($b) {
return $b->fizz($this->bar);
};
}
}
class B {
public function fizz ($buzz) {
return $buzz;
}
}
$mockA = new A;
$mockB = new B;
$callBack = $mockA->getCallback($mockB);
var_dump($callBack() === $mockA->foo());
Run Code Online (Sandbox Code Playgroud)
但是,如果您需要获取受保护属性的值,则应该为其定义公共 getter。这样,测试在 php 5.3 中也可以工作
归档时间: |
|
查看次数: |
2054 次 |
最近记录: |