通过Mockery中的代码设置对象集

时间:2016-04-21 10:14:07

标签: php phpunit mockery

我已经关注了要测试的代码。

// $generator, $locale, $site are parameters.
// It is just a part of real code.
$text = new Text();
$text->setType($generator->getType())
    ->setLocale($locale)
    ->setSite($site->getId());

/** @var $site \namespace\Site */
$site->addText($text);

为了测试这一点,我使用Mockery模仿Site。

在测试中,我一般都想做

$text = $site->getText();
$this->assertInstanceOF('\namespace\Text', $text);
$this->assertSame($generator->getType(), $text->getType());
$this->assertSame($locale, $text->getLocale());
$this->assertSame($site->getId(), $text->getSite());

在进行模拟时,我希望mock返回由原始代码创建的Text实例,并在行$site->addText($site)中设置。我试过了

$text = new Text();
$site = Mockery::mock(Site::class)
    ->shouldReceive('addText')
    ->with($text)
    ->andReturnUsing(function() {
            $args = func_get_args();
            return $args[0];
        })
    ->getMock();

这会在模拟代码中返回Text对象。在嘲弄中,有没有什么办法可以在原始代码中创建Text对象?

1 个答案:

答案 0 :(得分:2)

在这种情况下,您可以使用Mockery::on()方法。请参阅argument validation docs。在这里,您可以传递一个闭包,该闭包接收传递给addText方法的参数。您还可以在此闭包中使用PHPUnit断言来对$text参数执行断言。 像这样:

$site = Mockery::mock(Site::class)
    ->shouldReceive('addText')
    ->with(Mockery::on(function($text) {
        $this->assertInstanceOF('\namespace\Text', $text);
        //More assertions

        return true; //You must return true, otherwise the expectation will never pass regardless of the assertions above.
    }));