Mockery:使用不同的返回值测试链式方法调用(此处为:Symfony ProcessBuilder)

时间:2016-03-30 15:01:12

标签: php symfony mockery

我尝试使用Symfony Process测试创建2 + API docs个对象的方法(另请参阅ProcessBuilder)并且我已经运行了尝试返回不同的模拟过程对象时出现问题。事实上,我有点不确定Mockery是否可以做到这一点。

是否可以根据对象的调用链(包括参数)在Mockery的andReturn()中选择值?

理想情况下,我正在寻找这样的事情:

<?php
$processBuilderMock
    ->shouldReceive('setPrefix("test")->add("-f")->getProcess')
    ->andReturn($testProcess); 

完整示例:
如果文件不存在,以下代码将创建文件/tmp/dummy。它使用了两个命令test -f /tmp/dummytouch /tmp/dummy(我知道它是一个愚蠢的例子)。

<?php
class Toggler
{
    public function toggleFile(ProcessBuilder $builder)
    {
        $testProcess = $builder
            ->setPrefix('test')->setArguments(array('-f', '/tmp/dummy'))
            ->getProcess();

        $testProcess->run();

        if (!$testProcess->isSuccessful()) { // (a)
            $touchProcess = $builder
                ->setPrefix('touch')->setArguments(array('/tmp/dummy'))
                ->getProcess();

            $touchProcess->run();
            return $touchProcess->isSuccessful(); // (b) 
        } else {
            // ...
        }
    }
}

要测试所有情况,我需要能够模拟相应命令Processtest的{​​{1}}个对象(此处:touch和{{1} })。理想情况下,此测试代码如下所示:

$testProcess

但是,由于 Mockery不允许在调用链中使用参数,我在如何测试这种情况方面有点迷失。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这有点可怕,但你可以分别尝试进入调用链的每一步并让它返回mock $ builder。最后返回哪个进程取决于调用的顺序。

$builder->shouldRecieve('setPrefix')->with('test')->andReturn($builder);
$builder->shouldRecieve('setPrefix')->with('touch')->andReturn($builder);

$builder->shouldRecieve('getProcess')
    ->andReturnValues(array($testProcess, $touchProcess));

这感觉非常混乱,但这是我迄今为止能够找到的唯一方式。 (如果您发布此内容之后想出更好的内容,我很乐意看到。)