我是phpUnit测试的新手。我一直在尝试在一个程序中测试模型。模型扩展到BasicModel,其中设置了Doctrine EntityManager。每次我测试在BasicModel中调用此部分的方法时,我得到:
Fatal error: Call to a member function get() on a non-object in /pathTo/Model/BasicModel.php on line 53
第53行有
$this->setEntityManager($this->getServiceLocator()->get('Doctrine'ORM'EntityManager'));
问题是:我如何绕过这个?我试图模拟EntityManager和BasicModel,但结果总是一样的。我的测试看起来像这样:
class MyModelTest extends 'PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->sm = Bootstrap::getServiceManager();
$this->em = $this->sm->get('Doctrine'ORM'EntityManager');
$this->model = new MyModel($this->em);
$bm = $this->getMock('pathTo'Model'BasicModel');
$bm->expects($this->once())
->method('getEntityManager')
->will($this->returnValue($this->em));
parent::setUp();
}
public function testMyFunction()
{
$result = $this->model->myFunction();
$this->assertInstanceOf('myEntity', $result);
}
正在测试的方法如下所示:
class MyModel extends BasicModel {
public function myFunction()
{
$em = $this->getEntityManager();
$something = $em->getRepository('path'to'someEntity')->someMethod();
return $something;
}
}
(一些)BasicModel的方法看起来像这样:
class BasicModel implements ServiceLocatorAwareInterface {
protected function getEntityManager() {
if (null === $this->entityManager) {
$this->setEntityManager($this->getServiceLocator()
->get('Doctrine'ORM'EntityManager'));
}
return $this->entityManager;
}
public function setServiceLocator(ServiceLocatorInterface $sl) {
$this->serviceLocator = $sl;
return $this;
}
public function getServiceLocator() {
return $this->serviceLocator;
}
}
更新:我尝试了以下MyModelTest设置(如Tim Fountain建议的):
public function setUp()
{
$this->sm = Bootstrap::getServiceManager();
$this->model = new MyModel();
$this->model->setServiceLocator($this->sm);
parent::setUp();
}
但是结果是:
PDOException: SQLSTATE[HY000] [1045] Access denied for user
'username'@'localhost' (using password: YES)
那么接下来我该怎么做呢?:)
在您的setUp
-Method中,您将服务管理器分配给变量$this->sm
。但是当通过getServiceLocator
访问定位器时,您尝试使用$this->serviceLocator
。尝试先修复这个问题,然后在setUp
或Getter-Method中使用正确的变量名。
同样,你并不真正返回一个服务定位器。这只是服务管理器实现的模式/接口的名称。但这不是问题的一部分,只是一个提示;)