能否在Guzzle中间件中生成模拟响应?Drupal PHPUnit测试问询
在Drupal PHPUnit测试中用Guzzle中间件直接返回模拟响应
完全可以通过自定义中间件直接返回响应,绕过栈内后续中间件和底层处理器。只要在中间件回调里返回一个包装成Promise的Psr\Http\Message\ResponseInterface实例,Guzzle就会终止后续栈流程,直接使用该响应作为请求结果。
实现步骤
1. 编写自定义模拟中间件
针对目标URL编写拦截逻辑,直接返回预设的模拟响应:
use Psr\Http\Message\RequestInterface; use GuzzleHttp\Psr7\Response; function mockExampleResourceMiddleware() { return function (callable $handler) { return function (RequestInterface $request, array $options) use ($handler) { // 匹配需要模拟的目标URL if ($request->getUri()->__toString() === 'http://example.com/some-resource') { // 用Promise包装模拟响应,直接返回 return \GuzzleHttp\Promise\promise_for( new Response(200, [], json_encode(['key' => '模拟测试数据'])) ); } // 非目标请求继续走正常流程 return $handler($request, $options); }; }; }
2. 在Drupal测试中注入中间件
通过ClientFactory获取客户端实例时,将模拟中间件加入处理器栈的最顶部(确保优先执行):
// 获取Drupal的HTTP客户端工厂 $clientFactory = \Drupal::service('http_client_factory'); // 创建带模拟中间件的客户端 $client = $clientFactory->fromOptions([ 'handler' => function (\GuzzleHttp\HandlerStack $stack) { // 将中间件压入栈顶,优先拦截请求 $stack->unshift(mockExampleResourceMiddleware()); return $stack; }, ]); // 发起请求验证效果 $response = $client->get('http://example.com/some-resource'); $responseData = json_decode($response->getBody(), true); // $responseData 结果为 ['key' => '模拟测试数据']
扩展说明
- 执行顺序:用
unshift将中间件加到栈顶,保证它在Drupal默认中间件之前执行,优先拦截目标请求。 - 灵活匹配:可根据请求方法、请求头、请求体等条件,返回不同状态的模拟响应(如404、500错误)。
- Promise要求:必须用
promise_for将响应包装为已解决的Promise,符合Guzzle中间件的返回规范。
内容的提问来源于stack exchange,提问作者joachim
相关产品推荐
相关产品推荐

