Я пытаюсь написать единичный тест с 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'); } }
Doctrine 2 Entities следует рассматривать как любой старый класс. Вы можете издеваться над ними, как и любой другой объект в PHPUnit.
$mockCountry = $this->getMock('Country');
Начиная с PHPUnit 5.4, метод getMock () был лишен. Вместо этого используйте createMock () или getMockbuilder ().
Как отметил @beberlei, вы используете EntityManager внутри самого класса Entity, что создает ряд липких проблем и поражает одну из основных целей Doctrine 2, которая заключается в том, что Entity не связаны с их собственным сопротивлением. Эти методы «найти» действительно принадлежат классу репозитория .
У меня есть следующие функции 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
.
Можете ли вы показать, как вы введете $ this -> _ em в «Страна»? Кажется, вы смешиваете обязанности здесь, вводя EM в Entity. Это очень важно. В идеале в ваших моделях у вас будет бизнес-логика, которая передает свои зависимости, так что вам не нужна ссылка EntityManager.