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

Php Symfony5/Codeception:服务在容器中不可用,php,symfony,codeception,symfony5,Php,Symfony,Codeception,Symfony5,TL;DR 在Codeception测试中,我试图$I->grabService()。服务在控制器中工作,没有自定义配置,但我得到: Fail Service App\Service\Car在容器中不可用 完整故事 我有一个项目,其中包含一些服务,这些服务基本上是类,可以进行一些处理。所有服务都可以通过服务容器访问。我在功能套件中测试每一个类(还有一些在单元中),直到今天一切都很顺利 所以今天我添加了一个新的服务,当然还有一个测试。我做到了: root@9c80b567f681:/var/ww

TL;DR

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

Fail Service App\Service\Car在容器中不可用


完整故事

我有一个项目,其中包含一些
服务
,这些服务基本上是类,可以进行一些处理。所有
服务
都可以通过服务容器访问。我在功能套件中测试每一个类(还有一些在单元中),直到今天一切都很顺利

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

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)
    {
    }
}
<?php

namespace App\Service;

class Car
{

}
TL;博士 失败服务应用程序\服务\汽车在容器中不可用

现在,我所做的大多数其他测试都使用相同的概念:我在
\u before()
中获取服务,然后对其进行测试。除了我今天添加的任何类之外,所有的都通过:)WTF

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

My
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']
我花了一上午的时间安装/重新安装/重新启动电脑。。。我完全迷路了,很愚蠢。有人知道吗

编辑:

我注意到一些非常有趣的事情。如果我手动将服务添加到
services.yml
并设置
public:true
,那么我可以从Codeception使用它。但是请注意,对于我以前创建的任何其他服务,我都不必这样做。

TL;博士

问题似乎是Symfony在编译容器时删除了所有未使用的服务。你可以看到代码


当我注意到我的服务在显式设置为
public
时工作正常后,我开始仔细研究,我偶然发现有人也有同样的问题。更多的挖掘(以及与比我聪明的人交谈)让我找到了这个答案顶部的链接


只花了大约4天时间…

为什么需要使用
chown
?symfony/www数据是否可以看到该车型?尝试
php-bin/console-debug:container'App\Service\Car'
甚至
php-bin/console-debug:container
,查看它是否在那里。尝试在常规代码(例如控制器)中而不是在测试中使用此服务,看看它是否可以访问。@blahy您好,谢谢您的评论。是的,我可以使用它从控制器,我注入它通过构造函数和一切工作。同样在
debug:container
/
debug:autowiring
中,我可以正确地看到它。一切看起来都很好。你试过清理你的集装箱吗?另外,看看容器目录本身——应该有某种可能显示信息的“容器构建日志”。例如,如果未使用服务,则可以将其从容器中删除anywhere@NicoHaase我猜你指的是清理
var/cache
?我尝试删除整个目录并允许Symfony重新创建。我还尝试删除整个项目,从git中提取,然后重新安装供应商等等。所以
var
显然会自动重新创建。没有乐趣。@NicoHaase是的,所有这些看起来都和其他服务一模一样。在周末进行了更多的测试之后,我认为这可能与codeception有关,如果它不是显式公开的,就无法加载它。我添加了简短的
编辑
# 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']