我正在使用原则 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 调用的开头,以便它们具有正确的命名空间。