2017-06-13 98 views
0

大家好,我需要测试一段代码,调用另一个类的功能我现在不能编辑PHPUnit测试函数的值通过引用和返回值

我只需要测试它,但问题是这个函数有一个值通过引用和返回值,所以我不知道如何模拟它。

这列类的功能:

public function functionWithValuePassedByReference(&$matches = null) 
    { 
     $regex = 'my regex'; 

     return ($matches === null) ? preg_match($regex, $this->field) : preg_match($regex, $this->field, $matches); 
    } 

这是被称为点,并在那里我需要模拟:

$matches = []; 
    if ($column->functionWithValuePassedByReference($matches)) { 
     if (strtolower($matches['parameters']) == 'distinct') { 
      //my code 
     } 
    } 

所以我试图

$this->columnMock = $this->createMock(Column::class); 
    $this->columnMock 
     ->method('functionWithValuePassedByReference') 
     ->willReturn(true); 

如果我这样做返回我错误,索引parameters不存在明显,所以我试过这个:

$this->columnMock = $this->createMock(Column::class); 
    $this->columnMock 
     ->method('functionWithValuePassedByReference') 
     ->with([]) 
     ->willReturn(true); 

但同样的错误,我该如何嘲笑该功能?

感谢

回答

2

您可以使用->willReturnCallback()修改参数,并返回一个值。所以,你的模拟会变成这个样子:

$this->columnMock 
     ->method('functionWithValuePassedByReference') 
     ->with([]) 
     ->willReturnCallback(function(&$matches) { 
      $matches = 'foo'; 
      return True; 
     }); 

为了这个工作,你需要在生成模拟关闭克隆模仿的论点。所以你的模拟对象会像这样构建

$this->columnMock = $this->getMockBuilder('Column') 
     ->setMethods(['functionWithValuePassedByReference']) 
     ->disableArgumentCloning() 
     ->getMock(); 

这真的是代码气味,顺便说一句。我意识到你说过你不能改变你嘲笑的代码。但对于其他人来看这个问题,这样做会在你的代码中造成副作用,并且可能是修复错误非常令人沮丧的来源。

+0

是的,它的工作原理!非常感谢! –