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 天...
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 天...