Невозможно получить доступ к частной службе в тестовом контейнере во время phpunit - PullRequest
0 голосов
/ 22 мая 2019

В настоящее время я разрабатываю новый сервис, используя методы 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 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...