尝试模拟原则 2 实体存储库时在 PHPUnit 中出现错误


Getting errors in PHPUnit when trying to mock Doctrine 2 Entity Repository

我正在使用原则 2 构建一个 ZF2 应用程序,并尝试使用模拟对象对其进行测试。我尝试测试的原始操作如下:

public function indexAction()
{   
    $title = 'File Types';
    $this->layout()->title = $title;
    $em = $this->serviceLocator->get('entity_manager');
    $fileTypes = $em->getRepository('Resource'Entity'FileType')
        ->findBy(array(), array('type' => 'ASC'));
    return array(
        'title' => $title,
        'fileTypes' => $fileTypes
    );
}

在我的测试中,我使用以下方法来创建实体管理器和文件类型实体存储库的模拟:

public function mockFiletypeResult($output)
{
    $emMock = $this->getMockBuilder('Doctrine'ORM'EntityManager')
        ->disableOriginalConstructor()
        ->getMock();
    $repositoryMock = $this->getMock('Resource'Entity'FileType');
    $repositoryMock->expects($this->any())
        ->method('findBy')
        ->will($this->returnValue($output));
    $emMock->expects($this->any())
        ->method('getRepository')
        ->will($this->returnValue($repositoryMock));
    $this->getApplicationServiceLocator()->setAllowOverride(true);
    $this->getApplicationServiceLocator()->setService('Resource'Entity'FileType', $repositoryMock);
    $this->getApplicationServiceLocator()->setService('Doctrine'ORM'EntityManager', $emMock);
}

上面的代码是基于我在这篇文章中读到的关于stackoverflow的内容。

问题是,当我运行测试时,出现以下错误:Fatal error: Call to undefined method Mock_FileType_39345bde::findBy() in /path/to/test 。我做错了什么?我环顾了一堆,但似乎无法弄清楚问题所在。

编辑:我最初写的是错误消息抱怨未识别的findAll((方法,而实际上它是findBy((。

编辑2:此后,我尝试向我的实体存储库添加新方法,如下所示:

public function getFileTypes()
{
    $query = $this->_em->createQuery('SELECT t
        FROM Resource'Entity'FileType t
        ORDER BY t.type ASC, t.extension ASC');
    return $query->getResult();
}

然后,我尝试在我的控制器中用getFileType替换findBy方法,并在模拟中找出getFileType。同样的问题:它说找不到方法。

还有一件事:不确定这是否重要,但我使用的是 PHPUnit 版本 3.7。出于某种原因,我认为 4.x 版本无法在 ZF2 中正常工作。我应该升级吗?

如果你不在仓库上使用getMockBuilder(),它会希望你存根任何调用的方法。 如果使用 getMockBuilder() ,它将自动将所有函数替换为返回 null 的虚拟实现。

所以你可以使用模拟构建器

$repositoryMock =
    $this->getMockBuilder(''Doctrine'ORM'EntityRepository')->getMock();

或存根在其他地方调用的findBy()函数

$repositoryMock->expects($this->any())
    ->method('findBy')
    ->will($this->returnValue(null));

另请参阅: https://phpunit.de/manual/current/en/test-doubles.html

编辑:

我刚刚注意到你在嘲笑你的实体,但你需要嘲笑你的存储库或教义的。 请参阅我上面编辑的评论。 如果保留findBy()方法,则可以简单地模拟EntityRepository类。 如果您有自己的(例如资源''存储库''文件类型存储库(,则可以模拟它。

此外,您可能需要将'放在 MockBuilder 调用的开头,以便它们具有正确的命名空间。