Создайте несколько файлов классов специально для тестирования вашего автозагрузчика и поместите их в отдельную директорию (брат к тесту), которую вы можете зарегистрировать в автозагрузчике. Используйте class_exists($class, false)
, чтобы проверить, загружен ли класс без вызова автозагрузчика.
Примечание: Помогает, если вы разработали свой автозагрузчик нестатичным, чтобы вы могли создавать отдельный экземпляр для теста вместо тестирования активного.
Вот примеры для autoload()
метода моего пользовательского автозагрузчика в качестве примера:
function test_autoload_loadsExistingClass() {
$this->fixture->registerPrefix('TestClasses', self::$root . 'models');
if (class_exists('TestClasses_Autoloader_Foo', false)) {
self::error('Class TestClasses_Autoloader_Foo is already loaded');
}
$this->fixture->autoload('TestClasses_Autoloader_Foo');
if (!class_exists('TestClasses_Autoloader_Foo', false)) {
self::fail('Class TestClasses_Autoloader_Foo failed to load');
}
}
function test_autoload_silentlyIgnoresMissingClasses() {
$this->fixture->registerPrefix('Foo', self::$root . 'models');
$this->fixture->autoload('Foo_Bar');
}
function test_autoload_searchesIncludePathForUnknownPrefix() {
if (class_exists('TestClasses_Autoloader_Foo', false)) {
self::error('Class TestClasses_Autoloader_Foo is already loaded');
}
set_include_path(self::$root . 'include' . PATH_SEPARATOR . self::$savedIncludePath);
$this->fixture->autoload('TestClasses_Autoloader_Foo');
if (!class_exists('TestClasses_Autoloader_Foo', false)) {
self::fail('Class TestClasses_Autoloader_Foo failed to load');
}
}
Обновление: Ух ты, я не знаю, как я пропустил "Я не хочу зависеть от файла в файловой системе" в вашем вопросе, но это довольно важный вопрос. Вам нужно будет выполнить вызов include
в своем собственном методе вашего автозагрузчика (например, includeFile($path)
). Это позволит вам смоделировать метод во время теста, чтобы не задействовать файлы на диске. Кроме того, вы тестируете класс как обычно: передайте ему входные данные (как указано выше) классов для автоматической загрузки и проверьте, что ваш класс вызывает includeFile()
с правильными путями, когда это необходимо.
function testAutoloadLoadsExistingClass() {
$fixture = $this->getMock('MyAutoloader',
array('includeFile'), // mock the call to `include`
array(...)); // constructor args
$fixture->expects($this->once())
->method('includeFile')
->with('My/Package/Class')
->will($this->returnValue(true));
self::assertTrue($fixture->autoload('My_Package_Class'));
}