2010-08-26 3 views
11

Я пытаюсь написать модульный тест с phpunit для модели, использующей доктрину 2. Я хочу издеваться над сущностями доктрины, но я действительно не знаю, как это сделать. Может ли кто-нибудь объяснить мне, как мне это нужно? Я использую Zend Framework.Как создать макет объекта доктрины?

модель, которая должна быть проверена

class Country extends App_Model 
{ 
    public function findById($id) 
    { 
     try { 
      return $this->_em->find('Entities\Country', $id); 
     } catch (\Doctrine\ORM\ORMException $e) { 
      return NULL; 
     } 
    } 

    public function findByIso($iso) 
    { 
     try { 
      return $this->_em->getRepository('Entities\Country')->findOneByIso($iso); 
     } catch (\Doctrine\ORM\ORMException $e) { 
      return NULL; 
     } 
    } 
} 

Bootstrap.php

protected function _initDoctrine() 
{ 
    Some configuration of doctrine 
    ... 
    // Create EntityManager 
    $em = EntityManager::create($connectionOptions, $dcConf); 
    Zend_Registry::set('EntityManager', $em); 
} 

Расширенная модель

class App_Model 
{ 
    // Doctrine 2.0 entity manager 
    protected $_em; 

    public function __construct() 
    { 
     $this->_em = Zend_Registry::get('EntityManager'); 
    } 
} 

ответ

8

Doctrine 2 Entities следует рассматривать как любой старый класс. Вы можете издеваться над ними, как и любой другой объект в PHPUnit.

$mockCountry = $this->getMock('Country'); 

С точки зрения PHPUnit 5.4 метод getMock() был лишен. Вместо этого используйте createMock() или getMockbuilder().

Как отметил @beberlei, вы используете EntityManager внутри самого класса Entity, что создает ряд липких проблем и поражает одну из основных целей Doctrine 2, которая заключается в том, что Entity не связаны с их собственными настойчивость. Эти методы «найти» действительно принадлежат repository class.

+0

С вашим кодом Модельная страна будет издеваться? Вместо страны сущности. – tom

+0

В Доктрине 2 нет понятия «модель». Какую доктрину рассматривать как сущности, другие рамки могут рассматривать как модели. Или мне часто нравится ссылаться на «слой модели», который состоит из объектов и других классов (валидации, службы и т. Д.), Которые составляют всю модель данных. –

+0

Thx, для вашего комментария! У меня есть. – tom

1

Можете ли вы показать, как вы введете $ this -> _ em в «Country»? Кажется, вы смешиваете обязанности здесь, вводя EM в Entity. Это очень важно. В идеале в ваших моделях у вас будет бизнес-логика, которая передает свои зависимости, так что вам не нужна ссылка EntityManager.

+0

Привет, я обновил сообщение. О том, как инициализировать диспетчер объектов. – tom

15

У меня есть следующие функции setUp и tearDown для моих модульных тестов, которые используют Doctrine. Это дает возможность сделать доктрину звонки без него на самом деле прикасаясь к БД:

public function setUp() 
{ 
    $this->em = $this->getMock('EntityManager', array('persist', 'flush')); 
    $this->em 
     ->expects($this->any()) 
     ->method('persist') 
     ->will($this->returnValue(true)); 
    $this->em 
     ->expects($this->any()) 
     ->method('flush') 
     ->will($this->returnValue(true)); 
    $this->doctrine = $this->getMock('Doctrine', array('getEntityManager')); 
    $this->doctrine 
     ->expects($this->any()) 
     ->method('getEntityManager') 
     ->will($this->returnValue($this->em)); 
} 

public function tearDown() 
{ 
    $this->doctrine = null; 
    $this->em  = null; 
} 

Вы можете использовать $this->doctrine (или даже) $this->em при необходимости. Вам нужно будет добавить дополнительные определения методов, если вы хотите использовать remove или getRepository.

+1

Это создает новый объект EntityManager, который знает только, как упорствовать и скрываться в классе тестирования. Я верю, что просит ОП, заключается в том, чтобы издеваться над методами, которые сохраняются и скрываются из уже существующего объекта в его ServiceManager. Таким образом, его служебный код содержит persist() и flush(), и он касается БД, когда это всего лишь тест. –

Смежные вопросы