PHPUnit - тестовый класс автозагрузчика - PullRequest
5 голосов
/ 20 сентября 2011

Мне нужно создать автозагрузчик для моего приложения. Я не хочу зависеть от файла в файловой системе, так как я могу издеваться над новым вызовом? Или как вы тестируете класс автозагрузчика? Спасибо.

Ответы [ 3 ]

4 голосов
/ 22 сентября 2011

Или как вы тестируете класс автозагрузчика

Имхо, вам вообще не нужно тестировать ваш автозагрузчик модулем.

Если вы загрузите свое приложение, оно будетсбой эфира очень сложно, потому что он может найти все необходимые классы или ваш автозагрузчик работает нормально.

Каждый тест в вашем наборе тестов будет проверять, что автозагрузчик может загрузить «тестируемый класс», так что я не будуя не слишком беспокоюсь о модульном тестировании.

Может быть, вы называете это "интеграционным тестированием как побочным эффектом", если хотите, но я бы сказал, что это достаточно хорошо.

Если вы не думаетеэтого достаточно, я бы поместил оператор require / include в защищенную функцию и переопределил эту функцию в тестовом автозагрузчике и проверил, получает ли он правильные значения.

1 голос
/ 20 сентября 2011

Создайте несколько файлов классов специально для тестирования вашего автозагрузчика и поместите их в отдельную директорию (брат к тесту), которую вы можете зарегистрировать в автозагрузчике. Используйте 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'));
}
0 голосов
/ 30 сентября 2011

как вы тестируете класс автозагрузчика?

Зависит от того, что делает класс автозагрузчика.Например, вы можете проверить, работала ли регистрация обратного вызова автозагрузки с spl_autoload_register.

или если ваш автозагрузчик предоставляет функцию LoadLibrary, которая загружает все классы и интерфейсы вашей библиотеки, чтобы проверить, все ли классы былизагружен.Но это обычно зависело от файловой системы (что, я думаю, нормально).

...