代码之家  ›  专栏  ›  技术社区  ›  tom

如何创建实体的模拟对象?

  •  12
  • tom  · 技术社区  · 14 年前

    我试图用phpunit为一个使用原则2的模型编写一个单元测试。我想嘲笑教义实体,但我真的不知道怎么做。有人能解释一下我该怎么做吗?我正在使用Zend框架。

    需要测试的模型

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

    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 回复  |  直到 14 年前
        1
  •  8
  •   Mark Knapik Bryan M.    7 年前

    原则2实体应该像任何旧的阶级一样对待。你可以模仿他们,就像PHPUnit中的其他对象一样。

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

    从PHPUnit 5.4开始,getMock()方法已经被删除。改用createMock()或getMockbuilder()。

    正如@beberlei所指出的,您正在实体类本身内部使用EntityManager,这会产生许多棘手的问题,并破坏了原则2的一个主要目的,即实体不关心自身的持久性。那些“查找”方法真的属于 repository class .

        2
  •  15
  •   Jrgns    12 年前

    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 .

        3
  •  1
  •   beberlei    14 年前

    你能展示一下你是如何将这个->美元注入“国家”的吗?似乎您通过将EM注入实体来混合责任。这对可测试性有很大的危害。理想情况下,在您的模型中,您将拥有传递其依赖项的业务逻辑,这样您就不需要EntityManager引用。