shouldReceive('resolveForRoute') ->andReturnUsing(function (string $routeName, string $path, string $group, string $timing): array { IntegrationSpyMiddleware::$seen[] = "{$group},{$timing}"; return ($group === 'web' && $timing === 'after_core') ? [IntegrationSpyMiddleware::class] : []; }); $this->app->instance(ExtensionMiddlewareRegistryInterface::class, $registry); // web 그룹에 게이트를 파라미터 문자열로 등록한 라우트 (bootstrap 등록 형태 복제). Route::middleware([ ExtensionMiddlewareGate::class.':web,before_core', ExtensionMiddlewareGate::class.':web,after_core', ])->get('/__gate_probe', fn () => new Response('ok'))->name('gate.probe'); $response = $this->get('/__gate_probe'); $response->assertOk(); $response->assertSee('ok'); // 게이트가 group/timing 파라미터를 정확히 파싱해 registry 를 조회했는지 확인. $this->assertContains('web,before_core', IntegrationSpyMiddleware::$seen); $this->assertContains('web,after_core', IntegrationSpyMiddleware::$seen); // after_core 조회에서 반환된 매칭 미들웨어가 실제로 실행됐는지 확인. $this->assertTrue(IntegrationSpyMiddleware::$ran, '파라미터 문자열 파싱 후 매칭 미들웨어가 실행되어야 합니다.'); } } /** 실행/조회 기록 픽스처 미들웨어. */ class IntegrationSpyMiddleware { public static bool $ran = false; /** @var array */ public static array $seen = []; public function handle($request, \Closure $next) { self::$ran = true; return $next($request); } }