phpUnit在获取实体管理器时抛出对非对象的成员函数get()的调用


phpUnit throws "call to a member function get() on a non-object while getting Entity Manager

我是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中使用正确的变量名。

同样,你并不真正返回一个服务定位器。这只是服务管理器实现的模式/接口的名称。但这不是问题的一部分,只是一个提示;)