Laravel POST请求测试用例编写及多场景测试咨询
针对Laravel结账页面测试的解决方案
1. 验证结账POST请求无错误
直接编写Feature测试,发送构造好的POST请求,断言请求不会抛出异常,同时验证响应状态和会话无错误即可。示例代码:
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class CheckoutPostValidationTest extends TestCase { use RefreshDatabase; /** @test */ public function checkout_post_request_does_not_throw_errors() { // 自动创建测试用活动(日期自动设为未来一天) $event = \App\Models\Event::factory()->create([ 'date' => now()->addDay(), 'price' => 50.00, ]); // 构造符合要求的结账请求数据 $checkoutData = [ 'event_id' => $event->id, 'name' => 'Test User', 'email' => 'test@example.com', // 补充其他必填字段,如联系方式等 ]; // 发送POST请求并验证结果 $response = $this->post(route('checkout.process'), $checkoutData); // 根据业务逻辑调整状态码:比如成功后重定向用302,返回JSON用200 $response->assertStatus(302); $response->assertSessionHasNoErrors(); // 断言无表单验证错误 } }
2. Laravel路由全规格测试
完全可以对路由做全面测试,覆盖HTTP方法、权限控制、参数校验、响应逻辑等场景。示例:
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class CheckoutRouteFullTest extends TestCase { use RefreshDatabase; /** @test */ public function checkout_route_only_accepts_post_requests() { // 测试非POST请求被拒绝 $this->get(route('checkout.process'))->assertStatus(405); $this->put(route('checkout.process'))->assertStatus(405); // 测试POST请求可正常访问(即使数据不全,也应返回验证错误而非异常) $this->post(route('checkout.process'), [])->assertStatus(302); } /** @test */ public function checkout_route_requires_valid_event_id() { $invalidData = [ 'event_id' => 9999, // 不存在的活动ID 'name' => 'Test', 'email' => 'test@example.com', ]; $response = $this->post(route('checkout.process'), $invalidData); $response->assertSessionHasErrors('event_id'); } /** @test */ public function unauthenticated_users_can_access_checkout_route() { $event = \App\Models\Event::factory()->create(); $response = $this->post(route('checkout.process'), [ 'event_id' => $event->id, 'name' => 'Guest User', 'email' => 'guest@example.com', ]); $response->assertStatus(302); // 未登录用户可正常提交 } }
3. 用单元测试自动创建带新日期的活动
当然可以,借助Laravel的模型工厂,能自动生成带随机/指定日期的活动,完全替代手动创建。
首先在EventFactory中定义默认日期规则:
<?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; use App\Models\Event; class EventFactory extends Factory { protected $model = Event::class; public function definition() { return [ 'name' => $this->faker->sentence, 'date' => $this->faker->dateTimeBetween('+1 day', '+1 month'), // 自动生成未来1天到1个月的日期 'price' => $this->faker->randomFloat(2, 10, 100), 'is_free' => false, ]; } }
在测试中直接调用工厂创建,每次都会生成不同日期的活动:
// 创建免费活动 $freeEvent = \App\Models\Event::factory()->create(['is_free' => true, 'price' => 0.00]); // 创建带折扣的活动 $discountedEvent = \App\Models\Event::factory()->create(['price' => 100.00, 'discount_percent' => 20]);
4. 测试活动的各类场景
针对代金券、折扣、支付、免费活动等场景,分别编写测试用例:
免费活动场景
/** @test */ public function free_event_checkout_completes_without_payment() { $freeEvent = \App\Models\Event::factory()->create([ 'is_free' => true, 'price' => 0.00, ]); $checkoutData = [ 'event_id' => $freeEvent->id, 'name' => 'Free User', 'email' => 'free@example.com', ]; $response = $this->post(route('checkout.process'), $checkoutData); $response->assertRedirect(route('order.confirmation')); // 断言订单已创建且金额为0 $this->assertDatabaseHas('orders', [ 'event_id' => $freeEvent->id, 'total_amount' => 0.00, 'status' => 'completed', ]); }
折扣活动场景
/** @test */ public function discounted_event_applies_correct_price() { $discountedEvent = \App\Models\Event::factory()->create([ 'price' => 100.00, 'discount_percent' => 25, // 25%折扣 ]); $checkoutData = [ 'event_id' => $discountedEvent->id, 'name' => 'Discount User', 'email' => 'discount@example.com', ]; $this->post(route('checkout.process'), $checkoutData); // 断言订单金额为折扣后的75.00 $this->assertDatabaseHas('orders', [ 'event_id' => $discountedEvent->id, 'total_amount' => 75.00, ]); }
代金券场景
/** @test */ public function valid_coupon_applies_fixed_discount() { $event = \App\Models\Event::factory()->create(['price' => 80.00]); $coupon = \App\Models\Coupon::factory()->create([ 'code' => 'SAVE20', 'value' => 20.00, 'type' => 'fixed', ]); $checkoutData = [ 'event_id' => $event->id, 'name' => 'Coupon User', 'email' => 'coupon@example.com', 'coupon_code' => 'SAVE20', ]; $this->post(route('checkout.process'), $checkoutData); $this->assertDatabaseHas('orders', [ 'event_id' => $event->id, 'total_amount' => 60.00, 'coupon_id' => $coupon->id, ]); } /** @test */ public function invalid_coupon_triggers_error() { $event = \App\Models\Event::factory()->create(); $checkoutData = [ 'event_id' => $event->id, 'name' => 'Invalid Coupon User', 'email' => 'invalid@example.com', 'coupon_code' => 'INVALID', ]; $response = $this->post(route('checkout.process'), $checkoutData); $response->assertSessionHasErrors('coupon_code'); }
支付场景(模拟支付成功)
/** @test */ public function paid_event_checkout_completes_with_successful_payment() { $event = \App\Models\Event::factory()->create(['price' => 50.00]); // Mock支付网关,模拟支付成功 $this->mock(\App\Services\PaymentGateway::class, function ($mock) { $mock->shouldReceive('charge') ->with(50.00, anything()) ->andReturn(['success' => true, 'transaction_id' => 'txn_123']); }); $checkoutData = [ 'event_id' => $event->id, 'name' => 'Paid User', 'email' => 'paid@example.com', 'payment_method' => 'credit_card', 'card_number' => '4242424242424242', // 测试卡号 ]; $response = $this->post(route('checkout.process'), $checkoutData); $response->assertRedirect(route('order.confirmation')); $this->assertDatabaseHas('orders', [ 'event_id' => $event->id, 'total_amount' => 50.00, 'status' => 'paid', 'transaction_id' => 'txn_123', ]); }
内容的提问来源于stack exchange,提问作者B L Praveen
相关产品推荐
相关产品推荐

