Php 将返回值设为新函数
在向项目添加unittests的任务中,我已经多次遇到这个问题,问题是我需要返回一个函数作为返回值(并且不能更改类本身)。小例子:Php 将返回值设为新函数,php,function,unit-testing,mocking,phpunit,Php,Function,Unit Testing,Mocking,Phpunit,在向项目添加unittests的任务中,我已经多次遇到这个问题,问题是我需要返回一个函数作为返回值(并且不能更改类本身)。小例子: // The code has a: $thing->doFoo()->getBar(); // So I start the mock: $thingMock = $this->createMock(Thing::class); $thingMock->method('doFoo')->willReturn(/* WHAT DO I
// The code has a:
$thing->doFoo()->getBar();
// So I start the mock:
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn(/* WHAT DO I WRITE HERE? */);
然后是问题的第二部分,我想创建一个helper函数,在这里我可以定义
getBar
的结果:
private function createThingMock($example){
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn(/* WHAT HERE? I must return $example */);
}
我目前有以下内容,但在使用代码格式后,它非常庞大:
private function createThingMock($example){
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn(
new class($options)
{
private $options;
public function __construct($options) {
$this->options = $options;
}
public function getBar(): string
{
return $example ?? 'currently $example is always null';
}
}
);
}
这是一种代码格式之后的结果,正如您所看到的,对于感觉可以做得简单得多的事情来说,它非常庞大。建议?我不确定是否理解你的问题,所以如果我回答得不恰当,请原谅
我假设Thing::doFoo()
正在返回名为SubThing的类的实例。
我假设类子内容有一个名为doBar()的方法返回字符串
// The code has a:
$thing->doFoo()->getBar();
// So I start the mock:
$subThingMock = $this->createMock(SubThing::class);
$subThingMock->method('doBar')->willReturn('sample string');
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn($subThingMock);
如果子项
是名为ThingInterface
的接口的实现,则:
如果SubThing
是抽象类AbstractThing
的子类的实例,则:
在任何情况下,如果只想返回字符串,可以创建替换类:
class Substitution {
public function doBar(){
return 'sample string';
}
}
$subThing = new Substitution();
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn($subThing); //$subThing, not $subThingMock
$thing->doFoo()
必须返回一个特定类型的对象(至少从继承的角度来看),那么应该返回一个返回类的mock,然后该类可以实现getBar()
方法吗?当前阻碍我的问题是一个我不能简单模拟的类(我相信它是最终的或抽象的)。我只需要它返回一个字符串,我不需要原始函数(所以我有点幸运)。
$subThingMock = $this->getMockForAbstractClass(AbstractThing::class);
$subThingMock->method('doBar')->willReturn('sample string');
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn($subThingMock);
class Substitution {
public function doBar(){
return 'sample string';
}
}
$subThing = new Substitution();
$thingMock = $this->createMock(Thing::class);
$thingMock->method('doFoo')->willReturn($subThing); //$subThing, not $subThingMock