Php 是否可以模拟通过属性链接的方法?

Php 是否可以模拟通过属性链接的方法?,php,mocking,phpunit,Php,Mocking,Phpunit,我有以下PHP函数,我正试图为其编写一个PHPUnit测试: public function getDisplayMode() { if($this->request->query->get('master_video')) { return 'listTranslations'; } else { return 'default'; } } 行$this->request->query->get

我有以下PHP函数,我正试图为其编写一个PHPUnit测试:

public function getDisplayMode()
{
    if($this->request->query->get('master_video'))
    {
        return 'listTranslations';
    }
    else
    {
        return 'default';
    }
}
$this->request->query->get('master\u video')
就是我遇到的问题

我已经模拟了
请求
对象,因此如果它只是
$this->request->get('master_video')
,我可以很容易地使用
方法
方法告诉我的系统
get
应该返回什么

但是我不知道当假定
查询
属性存在时如何执行该操作。(例如,我不知道在我的模拟对象上有任何
属性
方法。)


有没有办法定义这里的
get
方法应该返回什么?

创建
query
的模拟,并指定在
->get()上发生的事情。测试结果会是这样的:

public function testGetDisplayMode() {
    $mockQuery = $this->getMockBuilder('Query') // Or whatever the query class is
         ->setMethods(['get'])
         ->getMock();

    $mockQuery->expects($this->once())
         ->method('get')
         ->with('master_video')
         ->willReturn('foo');

    $mockRequest = $this->getMockBuilder('Request') // Or whatever the request is
         ->getMock();

    $mockRequest->query = $mockQuery;

    $sut = new Bar($mockRequest) // Or however you instantiate the class with the mock request.

    $mode = $sut->getDisplayMode();
    // Do your assertions on the returned mode here.
}
作为一般规则,我发现当我做这样的事情时,我有一个模拟对象返回一个模拟对象,这是一种代码气味。这里的方法不需要$this->请求,它需要查询对象。您应该直接将其提供给对象,或者将其传递给此方法

如果不了解你正在上的课,我就不能给出更多的建议

如果有什么东西很难编写测试,这表明您的代码没有达到最佳设计。

谢谢!这起作用了。(我也同意代码的味道。在这种情况下,我正在为无法修改的类编写测试。)