![](/img/trans.png)
[英]Instantiate new class instance inside Symfony services (Best practice)
[英]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.