Symfony5 / Codeception:服务在容器中不可用

Symfony5 / Codeception: Service is not available in container

TL;DR

在 Codeception 测试中,我正在尝试 $I->grabService()。服务在控制器中工作,没有自定义配置,但我得到:

Fail Service App\Service\Car is not available in container


全文

我有一个项目有一些 Services 基本上是 classes,它们做一些处理。所有 Services 都可以通过服务容器访问。我正在功能套件(和一些单元)中测试每个 class,直到今天一切正常。

所以今天我添加了一项新服务,当然还有一项测试。我做到了:

root@9c80b567f681:/var/www/html# vendor/bin/codecept g:cest functional Service/Car
Test was created in /var/www/html/tests/functional/Service/CarCest.php

测试看起来像这样:

<?php

namespace App\Tests\Service;

use App\Service\Car;
use App\Tests\FunctionalTester;

class CarCest
{
    public function _before(FunctionalTester $I)
    {
        $I->grabService(Car::class);
    }

    public function tryToTest(FunctionalTester $I)
    {
    }
}

现在我在 PhpStorm 中手动创建一个新的 class。 Class 看起来像这样:

<?php

namespace App\Service;

class Car
{

}

这是我的测试输出:

root@9c80b567f681:/var/www/html# vendor/bin/codecept run tests/functional/Service/CarCest.php 
Codeception PHP Testing Framework v4.1.6
Powered by PHPUnit 9.2.6 by Sebastian Bergmann and contributors.
Running with seed: 


App\Tests.functional Tests (1) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
✖ CarCest: Try to test (0.00s)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Time: 00:01.616, Memory: 34.00 MB

There was 1 failure:

---------
1) CarCest: Try to test
 Test  tests/functional/Service/CarCest.php:tryToTest
 Step  Grab service "App\Service\Car"
 Fail  Service App\Service\Car is not available in container

Scenario Steps:

 1. $I->grabService("App\Service\Car") at tests/functional/Service/CarCest.php:12


FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

长话短说;博士 失败服务App\Service\Car在容器中不可用

现在我使用的大多数其他测试都使用相同的概念:我在 _before() 中获得服务,然后对其进行测试。一切都过去了,除了我今天添加的 class :) WTF?!?

顺便说一句: 如果我用之前创建的任何其他服务替换 $I->grabService(Car::class);,它工作正常。

我的 services.yaml 是标准的、开箱即用的 Symfony 版本。我总是简单地依赖于 src/* 中的所有内容都已经是服务这一事实。

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

我花了一上午installing/reinstalling/restartingPC...我完全迷路了,傻了。有人知道吗?

编辑:

我注意到一些非常有趣的事情。如果我手动将服务添加到 services.yml 并设置 public: true,那么我可以从 Codeception 使用它。但请注意,我不必为之前创建的任何其他服务执行此操作。

TL;DR

问题似乎是 Symfony 在容器编译时删除了所有未使用的服务。可以看到代码here on symfony project git page.


在我注意到,当我的服务明确设置为 public 时,我的服务可以正常工作后,我开始围绕它进行挖掘,我偶然发现了 git issue,那里有人遇到了同样的问题。更多的挖掘(和比我聪明的人交谈)让我看到了这个答案之上的 link。

BOOM! 只用了大约 4 天...