繁体   English   中英

如何在Symfony中实例化自动连线服务?

[英]How to instantiate autowired services in Symfony?

我想实例化OrderAbstraction服务,该服务需要一个测试用例中的构造函数中的实体管理器。

class OrderAbstraction
{
    ...

    /**
     * @var EntityManager
     */
    private $em;

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

我尝试自动连接OrderAbstractionTest并给定一个OrderAbstraction和实体管理器作为参数。

class OrderAbstractionTest extends TestCase
{
// tried with constructor and without it
    public function testDays(){
        $order = new OrderAbstraction();
        $order->dateFrom(new \DateTime('2019-08-20 14:00'));
        $order->dateTo(new \DateTime('2019-08-28 14:00'));

        $days = $order->days();
        $this->assertEquals(8, $days);
    }
}

我的service.yaml,自动连线设置为true

    App\Service\OrderAbstraction\:
        resource: '../src/Service/OrderAbstraction.php'
        arguments: 
            $em: '@Doctrine\ORM\EntityManager'

    App\Test\OrderAbstraction\:
        resource: '../tests/OrderAbstractionTest.php'
        arguments: 
            $em : '@Doctrine\ORM\EntityManager'

我不断得到这样的东西:

PHP致命错误:未被捕获的ArgumentCountError:函数App \\ Test \\ OrderAbstractionTest :: __ construct()的参数太少,在/var/www/html/autocom/bin/.phpunit/phpunit-6.5/src/Framework/TestSuite中传递了0。第476行上的php,/ var / www / html / autocom / tests / OrderAbstractionTest.php:13中恰好期望有1个

非常高兴知道如何将诸如OrderAbstraction之类的服务实例化到其他服务,测试。 因为大多数我都在控制器中执行以下操作:

$order = new OrderAbstraction($this->em);

如果autowire设置为true,则在services.yml中不需要任何内容​​。 OrderAbstraction.php中的EntityManagerInterface替换EntityManager,以获取在自动装配服务时自动注入的EntityManager实例。

OrderAbstraction.php

use Doctrine\ORM\EntityManagerInterface;

class OrderAbstraction {

  /**
   * @var EntityManager
   */
  private $em;

  public function __construct(EntityManagerInterface $em)
  {
    $this->em = $em;
    ...
  }
}

编辑

由于这将在基本控制器中按预期工作,因此您不能使用单元测试类的构造函数来注入服务。 根据Symfony的博客

在Symfony 4.1中,测试默​​认情况下允许获取私有服务。 实际上,基于WebTestCase和KernelTestCase的测试现在可以通过static :: $ container属性访问一个特殊的容器,该属性允许获取未删除的私有服务:

OrderAbstractionTest.php

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use App\Service\OrderAbstraction;

class OrderAbstractionTest extends WebTestCase {

  /**
   * @var OrderAbstraction
   */
  private $order;

  public function testDays() {
    self::bootKernel();
    $this->order = static::$container->get(OrderAbstraction::class);

    $this->order->dateFrom(new \DateTime('2019-08-20 14:00'));
    $this->order->dateTo(new \DateTime('2019-08-28 14:00'));

    $days = $this->order->days();
  }
}

经过测试并在Symfony 4.3上正常工作
有关更多有关Symfony 3.4和4.0的信息,请参见此答案

最终对我有用的是php单元模拟,我的代码现在看起来像这样:

    public function testDays(){
        $em = $this->getMockBuilder(EntityManager::class)
        ->disableOriginalConstructor()
        ->getMock();

        $order = new OrderAbstraction($em);
        $order->dateFrom(new \DateTime('2019-08-20 14:00'));
        $order->dateTo(new \DateTime('2019-08-28 14:00'));

        $days = $order->days();
        $this->assertEquals(8, $days);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM