如何在PEST PHP测试中无Mock测试Laravel Cashier结账重定向?
问题:Laravel Cashier订阅接口的无Mock测试方案
我有一个用于引导用户跳转到Stripe结账页的subscribeToPlan方法,代码如下:
public function subscribeToPlan(StripePlan $plan): \Laravel\Cashier\Checkout { return auth()->user()->newSubscription('default', $plan->plan_id)->checkout([ 'success_url' => route('admin.plans.index'), 'cancel_url' => route('admin.plans.index'), ]); }
对应的PEST测试用例:
test('User can subscribe to the Plan', function () { $plan = Plan::query()->first(); $checkout = $this->actingAs($this->user) ->get(route('admin.plans.purchase', $plan)); $this->assertInstanceOf(Checkout::class, $checkout); });
实际运行时发现,subscribeToPlan方法返回的并非声明的Checkout实例,而是Illuminate\Http\RedirectResponse——这是因为Laravel会自动将Cashier的Checkout对象转换为重定向响应。现在需要编写不使用Mock的正确测试用例。
解决方法
因为不能Mock,我们需要测试接口的实际行为而非返回的实例类型,核心是验证重定向的正确性:
- 断言响应是重定向状态(302)
- 验证重定向目标是Stripe结账域名
- 可选:校验URL中包含正确的计划ID、回调地址等关键参数
修改后的测试代码:
test('User can subscribe to the Plan', function () { // 准备测试数据 $plan = Plan::query()->first(); $successUrl = route('admin.plans.index'); $cancelUrl = route('admin.plans.index'); // 发起请求 $response = $this->actingAs($this->user) ->get(route('admin.plans.purchase', $plan)); // 1. 断言是重定向响应 $response->assertRedirect(); $this->assertInstanceOf(Illuminate\Http\RedirectResponse::class, $response); // 2. 断言重定向到Stripe结账域名 $redirectUrl = $response->headers->get('Location'); $this->str($redirectUrl)->contains('checkout.stripe.com'); // 3. 可选:校验URL中包含有效的Stripe会话ID parse_str(parse_url($redirectUrl, PHP_URL_QUERY), $queryParams); $this->assertNotEmpty($queryParams['session_id']); // (进阶)如果需要验证计划匹配,可通过Stripe测试API获取会话详情 // 需要提前配置Stripe测试密钥 // $session = \Stripe\Checkout\Session::retrieve($queryParams['session_id']); // $this->assertEquals($plan->plan_id, $session->line_items->data[0]->price->product); });
关键说明
- Laravel Cashier的
checkout()方法返回的Checkout对象实现了Responsable接口,Laravel会自动将其解析为RedirectResponse,所以控制器实际返回的是重定向而非原始Checkout实例。 - 不使用Mock的情况下,测试的核心是验证业务行为:用户被正确引导到Stripe结账页,且跳转参数符合预期。
- 如果需要验证计划ID等细节,可以通过Stripe的测试API获取结账会话详情,但需要提前配置测试环境的Stripe密钥。
内容的提问来源于stack exchange,提问作者Ask17
相关产品推荐
相关产品推荐

