Symfony 6.3+PHPUnit测试ETag缓存:二次请求未返回304问题
问题:Symfony 6.3测试ETag缓存时无法返回304状态码
在Symfony 6.3环境下使用PHPUnit 10.4测试端点ETag缓存功能时出现异常:控制器在实际HTTP客户端及调试场景中表现正常,但测试里第二次请求携带首次获取的ETag作为If-None-Match头时,返回200状态码而非预期的304。尝试调用客户端的disableReboot或reboot方法无效果,怀疑测试环节存在配置遗漏。
测试代码
public function testCache() { $client = static::createClient(); $client->request('GET', '/test?param=123'); $response = $client->getResponse(); $this->assertResponseIsSuccessful(); $etag = $response->getEtag(); $client->request('GET', '/test?param=123', [ 'headers' => [ 'If-None-Match' => $etag ] ]); $this->assertResponseStatusCodeSame(Response::HTTP_NOT_MODIFIED); // 实际返回200而非304 }
响应示例
HTTP/1.1 200 OK Age: 1 Cache-Control: public Content-Length: 76 Content-Type: application/json Date: Mon, 19 Feb 2024 22:03:45 GMT Etag: "bc4a907bcc4d3e601993f1646938d2a2" X-Content-Digest: en1c1a61e2a1702c01d3298b4b204a21dd X-Robots-Tag: noindex X-Symfony-Cache: GET /test?param=123&headers%5BIf-None-Match%5D=%22bc4a907bcc4d3e601993f1646938d2a2%22¶m2=321: stale, valid, store
可能的原因及解决办法
1. 测试环境未启用HTTP缓存
Symfony测试客户端默认不启用HTTP缓存,需手动配置。创建客户端时传入启用缓存的参数:
$client = static::createClient([], [ 'HTTP_CACHE' => true, ]);
2. 请求头传递方式错误
Symfony测试客户端传递自定义头时,需使用HTTP_前缀格式,或者调整参数传递位置。修改第二次请求的头信息传递方式:
$client->request('GET', '/test?param=123', [], [], [ 'HTTP_IF_NONE_MATCH' => $etag ]);
3. 缓存存储未共享
测试环境可能使用临时缓存驱动,导致两次请求无法共享缓存数据。在config/packages/test/framework.yaml中配置统一的缓存驱动:
framework: cache: app: cache.adapter.array system: cache.adapter.array
4. ETag生成逻辑不一致
检查控制器中ETag的生成逻辑,确保相同请求参数下生成的ETag完全一致,避免因额外参数、时间戳等因素导致ETag变化。
修改后的测试代码示例
public function testCache() { $client = static::createClient([], ['HTTP_CACHE' => true]); // 首次请求获取ETag $client->request('GET', '/test?param=123'); $this->assertResponseIsSuccessful(); $etag = $client->getResponse()->getEtag(); // 携带If-None-Match头发起第二次请求 $client->request('GET', '/test?param=123', [], [], [ 'HTTP_IF_NONE_MATCH' => $etag ]); $this->assertResponseStatusCodeSame(Response::HTTP_NOT_MODIFIED); }
内容的提问来源于stack exchange,提问作者Grokking
相关产品推荐
相关产品推荐

