我目前正在使用TDD方法开发一项新服务。从Symfony 4开始,默认情况下服务是私有的。 当我启动PHPunit时,尽管我使用了一个测试容器(旨在在PHPunit过程中访问私有服务),但是我的测试无法访问私有服务。
我正在使用PHP 7.1和Symfony 4.1。我有另一个服务,该服务也以相同的方式在同一文件中声明,可以在容器中找到它。 这两种服务之间的主要区别在于,我的“有问题的”服务不会作为依赖项注入到另一个服务中(到目前为止,它仅由我的测试使用)。
当我检查容器是否有我的服务时(使用has()方法),但测试容器返回false,但是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
谢谢您的时间:)