Как создать фиктивный объект из доктрины? - PullRequest
12 голосов
/ 26 августа 2010

Я пытаюсь написать модульный тест с 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');
    }
}

Ответы [ 3 ]

15 голосов
/ 26 января 2012

У меня есть следующие функции 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.

8 голосов
/ 31 августа 2010

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

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

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

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

1 голос
/ 31 августа 2010

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

...