symfony - 如何在 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,autowire 设置为 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 中的任何内容。将 EntityManager 替换为OrderAbstraction.php中的 EntityManagerInterface 以在自动装配服务时自动注入 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 的更多信息,
请参阅此 anwser
推荐阅读
- postgresql - 升级 postgresql 9.6 -> postgresql 13 因缺少 plpython2 扩展而被阻止,但我似乎无法删除扩展
- c# - 如何创建一个与另一个重叠的网格并在第二个网格中显示第一个网格的某些控件
- c - 为什么在 K&R 8.7 的 free() 的“for”循环的“for”循环的增量部分的测试部分没有增量?
- vb.net - 我的项目似乎已构建,但错误不断发生,我无法找出原因
- mongodb - 在我的 mongodb 数据库中创建文档后不执行数据库操作
- javascript - 我如何调整这个切片并替换 React
- octave - 示例程序中的问题未定义变量
- javascript - 如何在javascript中从dom中删除元素?
- django - 如何使用 is_grater_priority 制作绿色主体
- javascript - 每次单击按钮时都从 firebase 读取数据,而无需刷新