Symfony4功能测试中如何获取JWT编码器服务
在Symfony4 PHPUnit测试中获取JWT编码器生成令牌
我来帮你搞定这个问题!在Symfony的PHPUnit测试场景下,要获取LexikJWT的编码器服务其实很简单,下面给你两种实用的实现方式,适配控制器测试的需求:
方法一:通过WebTestCase的容器获取服务
如果你用的是WebTestCase(这是控制器测试的标准基类),可以直接从测试客户端的容器里拿到JWT编码器:
- 确保测试类继承WebTestCase
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class YourControllerTest extends WebTestCase { // ... 测试方法 }
- 在测试方法中获取编码器并生成令牌
public function testTokenValidReturns200() { // 创建测试客户端,启动内核 $client = static::createClient(); // 从容器中获取JWT编码器服务 $jwtEncoder = $client->getContainer()->get('lexik_jwt_authentication.jwt_encoder'); // 1. 准备测试用户的payload(可以从数据库加载真实用户,或者构造测试数据) // 比如先加载测试用户(假设你用Doctrine,需要获取实体管理器) $entityManager = $client->getContainer()->get('doctrine.orm.entity_manager'); $testUser = $entityManager->getRepository(User::class)->findOneBy(['username' => 'test_user']); // 构建JWT的payload数组 $payload = [ 'username' => $testUser->getUsername(), 'roles' => $testUser->getRoles(), 'exp' => time() + 3600, // 设置1小时后过期,避免测试中令牌失效 ]; // 2. 生成JWT令牌 $token = $jwtEncoder->encode($payload); // 3. 携带令牌请求目标接口 $client->request( 'GET', '/your-protected-endpoint', [], // 请求参数 [], // 文件上传 ['HTTP_AUTHORIZATION' => 'Bearer ' . $token] // 设置Authorization头 ); // 断言响应状态码为200 $this->assertEquals(200, $client->getResponse()->getStatusCode()); }
方法二:构造带错误权限的令牌测试403响应
要测试403(权限不足)的场景,只需要生成一个角色不满足接口要求的令牌即可:
public function testTokenInsufficientRoleReturns403() { $client = static::createClient(); $jwtEncoder = $client->getContainer()->get('lexik_jwt_authentication.jwt_encoder'); // 构造一个只有普通用户角色的payload(假设接口需要ROLE_ADMIN) $payload = [ 'username' => 'regular_user', 'roles' => ['ROLE_USER'], 'exp' => time() + 3600, ]; $token = $jwtEncoder->encode($payload); $client->request( 'GET', '/admin-only-endpoint', [], [], ['HTTP_AUTHORIZATION' => 'Bearer ' . $token] ); $this->assertEquals(403, $client->getResponse()->getStatusCode()); }
注意事项
- 如果你还没有测试用户,可以在测试方法里创建并持久化一个临时用户,或者用Doctrine Fixtures在测试前加载测试数据。
- 确保
lexik_jwt_authentication.jwt_encoder服务在测试环境中是可用的(默认情况下LexikBundle会自动配置)。 - 如果你用的是
KernelTestCase而非WebTestCase,可以通过static::bootKernel()启动内核,然后用static::$container->get(...)获取服务。
内容的提问来源于stack exchange,提问作者syl.fabre
相关产品推荐
相关产品推荐

