assertIsArray($module->getSeeders()); $this->assertEmpty($module->getSeeders()); } /** * getSeeders()를 오버라이드하여 특정 시더만 반환하는 경우를 테스트합니다. */ public function test_module_can_override_get_seeders(): void { $module = new class extends AbstractModule { public function getName(): string|array { return 'Test Module'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test description'; } public function getSeeders(): array { return [ 'App\\Database\\Seeders\\TestSeeder', ]; } }; $seeders = $module->getSeeders(); $this->assertCount(1, $seeders); $this->assertEquals('App\\Database\\Seeders\\TestSeeder', $seeders[0]); } /** * getSeeders()가 비어있지 않으면 해당 목록만 실행하는지 테스트합니다. */ public function test_run_module_seeders_uses_defined_seeders_when_not_empty(): void { // Mock 시더 클래스명 (실제 존재하지 않는 클래스) $fakeSeederClass = 'Tests\\Fixtures\\FakeSeeder'; // ModuleManager의 runModuleSeeders는 protected이므로 리플렉션 사용 $moduleManager = app(ModuleManager::class); $module = $this->createMock(ModuleInterface::class); $module->method('getSeeders')->willReturn([$fakeSeederClass]); // class_exists가 false이므로 Artisan::call이 호출되지 않아야 함 Artisan::shouldReceive('call')->never(); // 리플렉션을 통해 protected 메서드 호출 $method = new \ReflectionMethod(ModuleManager::class, 'runModuleSeeders'); $method->setAccessible(true); $method->invoke($moduleManager, $module); // 여기까지 예외 없이 도달하면 성공 $this->assertTrue(true); } /** * getSeeders()가 빈 배열이면 glob 방식으로 폴백하는지 테스트합니다. */ public function test_run_module_seeders_falls_back_to_glob_when_empty(): void { $moduleManager = app(ModuleManager::class); $module = $this->createMock(ModuleInterface::class); $module->method('getSeeders')->willReturn([]); // modules 프로퍼티가 비어있으므로 디렉토리명을 찾지 못해 early return $method = new \ReflectionMethod(ModuleManager::class, 'runModuleSeeders'); $method->setAccessible(true); $method->invoke($moduleManager, $module); // glob 폴백 경로에서 moduleDirName을 찾지 못해 early return (예외 없음) $this->assertTrue(true); } /** * registerExtensionAutoloadPaths가 모듈의 PSR-4 네임스페이스를 Composer ClassLoader에 등록하는지 테스트합니다. */ public function test_register_extension_autoload_paths_registers_psr4_namespaces(): void { // sirsoft-ecommerce 모듈의 composer.json이 존재하는지 확인 $composerFile = base_path('modules/sirsoft-ecommerce/composer.json'); if (! file_exists($composerFile)) { $this->markTestSkipped('sirsoft-ecommerce 모듈이 존재하지 않습니다.'); } // 동적 오토로드 등록 실행 ExtensionManager::registerExtensionAutoloadPaths('modules', 'sirsoft-ecommerce'); // Composer ClassLoader에서 등록된 PSR-4 프리픽스 확인 $loader = require base_path('vendor/autoload.php'); $prefixes = $loader->getPrefixes() + $loader->getPrefixesPsr4(); $this->assertArrayHasKey( 'Modules\\Sirsoft\\Ecommerce\\Database\\Seeders\\', $prefixes, 'SequenceSeeder 네임스페이스가 Composer ClassLoader에 등록되어야 합니다.' ); } /** * sirsoft-ecommerce 모듈의 getSeeders()가 SequenceSeeder만 반환하는지 테스트합니다. */ public function test_ecommerce_module_get_seeders_returns_sequence_seeder_only(): void { $moduleManager = app(ModuleManager::class); $moduleManager->loadModules(); $module = $moduleManager->getModule('sirsoft-ecommerce'); if (! $module) { $this->markTestSkipped('sirsoft-ecommerce 모듈이 설치되어 있지 않습니다.'); } $seeders = $module->getSeeders(); $this->assertCount(1, $seeders); $this->assertEquals( 'Modules\\Sirsoft\\Ecommerce\\Database\\Seeders\\SequenceSeeder', $seeders[0] ); } }