views:

181

answers:

2

Hi,

I'm trying to write a unit test with phpunit for a model that uses doctrine 2. I want to mock the doctrine entities but I really don't have a clue of how to do this. Can anyone explain to me how I need to do this? I'm using Zend Framework.

The model that needs to be tested

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);
}

Extended model

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

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

Can you show how you inject $this->_em into "Country"? It seems you mix responsibilities here by injecting the EM into an Entity. This does harm testability very much. Ideally in your models you would have business logic that is passed its dependencies, so that you don't need the EntityManager reference.

beberlei
Hi, I updated my post. On how I initialize the entity manager.
Skelton
+3  A: 

Doctrine 2 Entities should be treated like any old class. You can mock them just like any other object in PHPUnit.

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

As @beberlei noted, you are using the EntityManager inside the Entity class itself, which creates a number of sticky problems, and defeats one of the major purposes of Doctrine 2, which is that Entity's aren't concerned with their own persistance. Those 'find' methods really belong in a repository class.

Bryan M.
With your code the Model Country will be mocked? Instead of the entity Country.
Skelton
There is no concept of 'model' in Doctrine 2. What doctrine considers as Entities, other frameworks may consider as Models. Or, I often like to refer to the 'model layer' which consists of Entities and other classes (validations, services, etc) that comprise the entire data model.
Bryan M.
Thx, for your comment! I've got now.
Skelton