API Platform测试中随机出现/api/auth控制器找不到问题求助
问题背景
在API Platform项目中使用LexikJWTAuthenticationBundle实现认证,测试时调用配置的登录端点/api/auth获取JWT令牌,但测试执行时会随机出现以下错误:
Unable to find the controller for path "/api/auth". The route is wrongly configured.
测试结果不稳定,有时全部通过,有时部分测试用例失败。
相关配置
LexikJWTAuthenticationBundle配置:
lexik_jwt_authentication: secret_key: '%env(resolve:JWT_SECRET_KEY)%' public_key: '%env(resolve:JWT_PUBLIC_KEY)%' pass_phrase: '%env(JWT_PASSPHRASE)%' api_platform: check_path: /api/auth username_path: email password_path: password
routes.yaml配置:
api_auth: path: /api/auth methods: ['POST']
测试类代码
<?php declare(strict_types=1); namespace App\Tests\IntegrationTests\Api\XY; use ApiPlatform\Symfony\Bundle\Test\ApiTestCase; use ApiPlatform\Symfony\Bundle\Test\Client; use Spatie\Snapshots\MatchesSnapshots; class CanConnectTest extends ApiTestCase { use MatchesSnapshots; private Client $client; private string $token; protected function setUp(): void { $client = self::createClient(); $response1 = $client->request('POST', '/api/auth', [ 'headers' => [ 'Content-Type' => 'application/json', ], 'json' => [ 'email' => 'apiuser@domain.de', 'password' => 'apiuser', ], ]); $json = $response1->toArray(); self::assertResponseIsSuccessful(); self::assertArrayHasKey('token', $json); $this->token = $json['token']; $this->client = $client; } public function testCanConnectTrue(): void { $response = $this->client->request( 'GET', 'http://localhost/api/audiosus/can_connect/store/7', [ 'auth_bearer' => $this->token, 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ], ], ); self::assertResponseIsSuccessful(); self::assertMatchesJsonSnapshot($response->toArray()); } public function testCanConnectFalse(): void { $response = $this->client->request( 'GET', 'http://localhost/api/audiosus/can_connect/store/6', [ 'auth_bearer' => $this->token, 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ], ], ); self::assertResponseIsSuccessful(); self::assertMatchesJsonSnapshot($response->toArray()); } public function testCanConnectNotFound(): void { $this->client->request( 'GET', 'http://localhost/api/audiosus/can_connect/store/12312313213', [ 'auth_bearer' => $this->token, 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ], ], ); self::assertResponseStatusCodeSame(404); } }
解决思路
补全路由的控制器配置
当前routes.yaml中只定义了路径和请求方法,缺少指定LexikJWT自带的认证控制器,Symfony在部分测试场景下无法自动匹配到正确的控制器,导致随机失败。修改路由配置:api_auth: path: /api/auth methods: ['POST'] controller: lexik_jwt_authentication.controller.authentication_token验证测试环境的路由加载
执行bin/console debug:router --env=test命令,确认测试环境下/api/auth路由存在且控制器指向正确。同时检查config/packages/test/routing.yaml,确保没有排除该路由或LexikJWT的路由配置。隔离测试客户端状态
当前测试类的setUp中创建的客户端被所有测试用例共享,可能存在状态残留问题。可以在tearDown中清理客户端实例:protected function tearDown(): void { parent::tearDown(); unset($this->client, $this->token); }另外,将测试中的API请求改为相对路径(如
/api/audiosus/can_connect/store/7),避免绝对路径带来的客户端状态异常。禁用测试环境的路由缓存
测试环境下的路由缓存可能导致配置更新不及时,在phpunit.xml中设置缓存驱动为内存数组,避免文件缓存的随机问题:<php> <env name="APP_ENV" value="test" /> <env name="APP_DEBUG" value="1" /> <env name="CACHE_DRIVER" value="array" /> </php>关闭测试并行执行
如果使用phpunit --parallel并行运行测试,可能出现资源竞争导致路由加载异常。尝试关闭并行测试,或者确保每个测试进程的缓存独立。
内容的提问来源于stack exchange,提问作者Anton

