在Symfony 2中编写可测试服务并推动使用DiC

时间:2012-05-30 10:39:34

标签: testing dependency-injection symfony doctrine-orm

我需要在我的MyEntityRepository服务中调用一些方法。我已经看到了一些关于注入@doctrine.orm.default_entity_manager以获取所需存储库的示例:

namespace Acme\HelloBundle\Service;     

use Doctrine\ORM\EntityManager;

Class MyService
{
    private $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function doStuff()
    {
        $repo = $this->entityManager->getRepository('AcmeHelloBundle:MyEntity');

        // Do stuff
    }
}

使用此服务定义:

my_service:
  class: Acme\HelloBundle\Service\MyService
  arguments: ['@doctrine.orm.default_entity_manager']

问题此代码是否可测试为了将来的测试目的(使用模拟对象作为存储库)注入MyEntityRepository会更好吗?

namespace Acme\HelloBundle\Service;

use Acme\HelloBundle\Repository\MyEntityRepository;

Class MyService
{
    private $er;

    public function __construct(MyEntityRepository $er) { $this->er = $er; }

    public function doStuff()
    {
        $repo = $this->er;

        // Do stuff
    }
}

使用:

my_entity_repository:
  class: Acme\HelloBundle\Repository\MyEntityRepository
  factory_service: doctrine.orm.default_entity_manager
  factory_method: getRepository
  arguments: ['Acme\HelloBundle\Entity\MyEntity']

my_service:
  class: Acme\HelloBundle\Service\MyService
  arguments: ['@my_entity_repository']

1 个答案:

答案 0 :(得分:0)

我认为实体存储库比实体管理器更容易模拟,因为您必须模拟getRepository以返回实体存储库模拟,因此在这两种情况下,您都必须创建实体存储库模拟。

但这并不是我认为第二种解决方案更好的唯一原因:你的依赖关系更加清晰,人们可以看到你的类真正需要什么(实体管理器不使用其他方法)。

使用第二种解决方案会使对象的创建更具参与性,但这是DIC可以解决的问题。