【问题标题】:Set object set by code in Mockery在 Mockery 中设置由代码设置的对象
【发布时间】:2016-08-14 11:20:45
【问题描述】:

我有以下要测试的代码。

// $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 模拟站点。

在测试中,我一般都想做

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

在制作模拟时,我希望模拟返回由原始代码创建并在$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 对象?

【问题讨论】:

    标签: php phpunit mockery


    【解决方案1】:

    在这种情况下,您可以使用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.
        }));
    

    【讨论】:

    • 谢谢@bram,我也有类似的问题,您提供的解决方案似乎最适合我的问题。
    猜你喜欢
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2021-10-07
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多