【问题标题】:PHPUnit test function with value passed by reference and a returned valuePHPUnit 测试函数,通过引用传递值和返回值
【发布时间】:2017-06-13 09:39:51
【问题描述】:

大家好,我需要测试一段代码,该代码调用另一个类的函数,我现在无法编辑

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

这是列类的功能:

    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);

但同样的错误,我该如何模拟该函数?

谢谢

【问题讨论】:

    标签: php unit-testing phpunit


    【解决方案1】:

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

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

    为了使其正常工作,您需要在构建模拟时关闭克隆模拟的参数。所以你的模拟对象会像这样构建

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-24
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      相关资源
      最近更新 更多