В настоящее время я разрабатываю новый сервис, используя методы TDD. Начиная с Symfony 4, сервисы по умолчанию являются частными.
Когда я запускаю PHPunit, мой тест не может получить доступ к частной службе, хотя я использую тестовый контейнер (предназначенный для доступа к частным службам во время процесса PHPunit).
Я использую PHP 7.1 и Symfony 4.1. У меня есть другой сервис, также объявленный в том же файле, который находится в контейнере.
Основное различие между этими двумя службами состоит в том, что мой «проблемный» сервис не внедряется как зависимость в другой сервис (пока он используется только моим тестом).
Тестовый контейнер возвращает мне false, когда я проверяю, есть ли у меня сервис (с помощью метода has ()), но команда debug:container
находит его в тестовой среде.
Конечно, объявление моей службы как общедоступной решает проблему (пока это мое "исправление"). Кроме того, внедрение моего сервиса в другой сервис решает проблему. Но я должен иметь доступ к своему сервису без ограничений во время тестов.
Файл декларации сервиса:
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="openjet.off_company_duty_counter_value.generator.class">Openjet\Component\Duty\Generator\OffCompanyDutyCounterValueGenerator</parameter>
<parameter key="openjet.generator.document_id.class">Openjet\Component\Document\Generator\DocumentIdGenerator</parameter>
<parameter key="openjet.generator.invoice_cancel.class">Openjet\Component\Document\Generator\InvoiceCancelGenerator</parameter>
</parameters>
<services>
<service id="openjet.generator.off_company_duty_counter_value" class="%openjet.off_company_duty_counter_value.generator.class%">
<argument type="service" id="openjet.factory.off_company_duty_counter_value"/>
<argument type="service" id="openjet.manager.off_company_duty_counter_value"/>
<argument type="service" id="openjet.factory.counter_value"/>
</service>
<!-- working service -->
<service id="openjet.generator.document_id" class="%openjet.generator.document_id.class%">
<argument type="service" id="openjet.generator.invoice_id"/>
<argument type="service" id="openjet.generator.quotation_id"/>
<argument type="service" id="openjet.generator.boarding_pass_id"/>
<argument type="service" id="openjet.generator.proforma_id"/>
</service>
<!-- problematic service -->
<service id="openjet.generator.invoice_cancel" class="%openjet.generator.invoice_cancel.class%">
<argument type="service" id="openjet.manager.document"/>
</service>
</services>
</container>
Сам сервис:
<?php
declare(strict_types=1);
namespace Openjet\Component\Document\Generator;
use Doctrine\ORM\EntityManagerInterface;
use Openjet\Component\Document\Model\DocumentInterface;
// Nothing fancy in the interface, just the generate method
final class InvoiceCancelGenerator implements InvoiceCancelGeneratorInterface
{
/** @var EntityManagerInterface */
private $documentManager;
public function __construct(EntityManagerInterface $documentManager)
{
$this->documentManager = $documentManager;
}
public function generate(DocumentInterface $document): DocumentInterface
{
$now = new \DateTime();
$invoiceCancel = clone $document;
$document->setActiveState(DocumentInterface::ACTIVE_STATE_NOK);
$invoiceCancel
->setThirdPartyCreatedAt(null)
->setThirdPartyUpdatedAt(null)
->setSentAt($document->getSentAt())
->setCreatedAt($now)
->setUpdatedAt($now)
;
$this->documentManager->persist($invoiceCancel);
return $invoiceCancel;
}
}
Вызов в тесте:
$invoiceCancel = $this->get('openjet.generator.invoice_cancel')->generate($invoice);
В этом вызове $this->get()
используется static::$container
, который в контексте тестирования является конкретным тестовым контейнером, а не традиционным контейнером.
Ожидаемым результатом должно быть прохождение теста (или, как минимум, другая ошибка или сбой).
Текущий результат - ошибка в тесте и это сообщение:
1) Openjet\Tests\Bundle\AppBundle\Document\Generator\InvoiceCancelGeneratorTest::testGenerate
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: The "openjet.generator.invoice_cancel" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.
/Users/adrien/projects/openjet/vendor/symfony/dependency-injection/Container.php:260
/Users/adrien/projects/openjet/vendor/symfony/dependency-injection/Container.php:222
/Users/adrien/projects/openjet/vendor/polishsymfonycommunity/symfony-mocker-container/src/PSS/SymfonyMockerContainer/DependencyInjection/MockerContainer.php:56
/Users/adrien/projects/openjet/vendor/symfony/framework-bundle/Test/TestContainer.php:102
/Users/adrien/projects/openjet/tests/KernelTestCaseContainerTrait.php:24
/Users/adrien/projects/openjet/tests/Bundle/AppBundle/Document/Generator/InvoiceCancelGeneratorTest.php:27
Спасибо за ваше время :) 1026 *