如何测试路由中间件?Laravel路由示例及测试类型确认
嘿,这个问题问得很实在!我来给你捋清楚这两个关键点:
如何测试这些路由确实受
verified中间件保护? 核心思路是模拟两种用户场景:未验证邮箱的用户访问路由时应该被重定向到验证页面,而已验证的用户则能正常访问。用Laravel自带的测试框架(PHPUnit)可以这样写:
首先,测试未验证用户的访问行为(这是重点,因为我们要验证中间件的拦截逻辑):
<?php namespace Tests\Feature; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class VerifiedMiddlewareTest extends TestCase { use RefreshDatabase; /** * 测试未验证用户无法访问受保护的路由 * @dataProvider protectedRoutesProvider */ public function test_unverified_users_cannot_access_protected_routes(string $routeName) { // 创建一个未验证邮箱的用户(email_verified_at 字段为 null) $unverifiedUser = User::factory()->unverified()->create(); // 以该用户身份发起请求 $response = $this->actingAs($unverifiedUser)->get(route($routeName)); // 断言被重定向到邮箱验证提示页面 $response->assertRedirect(route('verification.notice')); } /** * 测试已验证用户可以正常访问受保护的路由 */ public function test_verified_users_can_access_protected_routes() { // 创建一个已验证邮箱的用户(默认工厂生成的用户是已验证状态) $verifiedUser = User::factory()->create(); // 测试 profile 路由 $profileResponse = $this->actingAs($verifiedUser)->get(route('profile.show')); $profileResponse->assertOk(); // 断言返回200状态码 // 测试 settings 路由 $settingsResponse = $this->actingAs($verifiedUser)->get(route('settings.show')); $settingsResponse->assertOk(); } // 数据提供者,避免重复编写测试代码 public function protectedRoutesProvider() { return [ ['profile.show'], ['settings.show'], ]; } }
几点补充说明:
- 使用
RefreshDatabasetrait可以保证每次测试都是干净的数据库环境 User::factory()->unverified()->create()需要你的User工厂支持unverified状态,比如在工厂里定义一个状态方法:public function unverified(): static { return $this->state(fn (array $attributes) => [ 'email_verified_at' => null, ]); }- 如果你的验证提示路由不是默认的
verification.notice,记得改成你项目里对应的路由名称
这种测试属于功能测试还是单元测试?
毫无疑问,这属于功能测试。
原因很简单:我们不是在孤立地测试verified中间件这个类的单个方法(那是单元测试的范畴),而是在测试整个请求流程的行为:用户发起请求,中间件拦截/放行,路由最终返回正确的响应。功能测试关注的是系统的整体行为是否符合业务预期,模拟的是真实用户的操作场景。
如果是单元测试,你可能会直接实例化VerifiedMiddleware类,传入模拟的请求和闭包,测试它的handle方法是否正确触发重定向或放行——但那只是测试中间件本身的逻辑,而我们这里的测试是验证路由和中间件的组合是否能正确保护资源,属于功能层面的验证。
内容的提问来源于stack exchange,提问作者rook
相关产品推荐
相关产品推荐

