You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel测试中如何在单次测试内切换Http fake响应数据?

解决Laravel中Http::fake()多次设置不生效的问题

问题原因

Laravel的Http::fake()会将HTTP客户端替换为FakeHttpClient实例,后续调用Http::fake()不会重新创建新的Fake实例,而是在现有实例上追加匹配规则,导致相同URL的旧规则仍优先生效。

解决方案1:用动态回调根据调用次数返回不同响应

通过闭包维护调用计数器,根据次数返回对应响应:

$callCount = 0;

Http::fake([
    'https://my.apicall.com/api/v1/Invoice/Factory/saveInvoice' => function () use (&$callCount, $invoiceBody, $invoiceBody2) {
        $callCount++;
        return $callCount === 1 
            ? Http::response($invoiceBody, 201) 
            : Http::response($invoiceBody2, 201);
    },
]);

// 执行第一次触发API调用的代码
// 执行第二次触发API调用的代码

解决方案2:重置HTTP客户端实例

在第二次调用Http::fake()前,先清除已绑定的Fake客户端实例:

// 第一次伪造响应
Http::fake([
    'https://my.apicall.com/api/v1/Invoice/Factory/saveInvoice' => Http::response($invoiceBody, 201),
]);

// 执行部分代码

// 重置Fake客户端
app()->forgetInstance('http.client');
// 部分Laravel版本可直接用Http::reset(),若不存在则用上面的forgetInstance

// 第二次伪造响应
Http::fake([
    'https://my.apicall.com/api/v1/Invoice/Factory/saveInvoice' => Http::response($invoiceBody2, 201),
]);

// 执行更多代码

解决方案3:使用全局Fake并动态覆盖规则

先初始化全局Fake,再在每次调用前重新设置对应URL的响应规则:

// 初始化全局Fake
Http::fake();

// 第一次调用前设置响应
Http::fake([
    'https://my.apicall.com/api/v1/Invoice/Factory/saveInvoice' => Http::response($invoiceBody, 201),
]);
// 执行第一次代码

// 第二次调用前覆盖响应规则
Http::fake([
    'https://my.apicall.com/api/v1/Invoice/Factory/saveInvoice' => Http::response($invoiceBody2, 201),
]);
// 执行第二次代码

注:此方法在部分Laravel版本中可能存在规则优先级问题,优先推荐前两种方案。

内容的提问来源于stack exchange,提问作者Christian Wagner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:43:16