Перегрузка PHP в приватные свойства и методы модульного теста - PullRequest
8 голосов
/ 19 февраля 2011

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

В тесте, над которым я работал, я хотел подтвердить, что прохождениеопределенный параметр объекта привел к установке свойства.Я использую SimpleTest для обучения юнит-тестированию, и мой метод тестирования выглядит следующим образом:

function test__Construction_Should_Properly_Set_Tables() {
  $cv = new CVObject( array( 'tables' => $this->standardTableDef ) );
  $tables = $cv->tables;
  $this->assertEqual( $tables, $this->standardTableDef );
}

Затем я написал метод __get в CVObject следующим образом:

function __get( $name ) {
  $trace = debug_backtrace();
  $caller = $trace[1];
  $inTesting = preg_match( '/simpletest/', $caller['file'] );

  if ( $inTesting ) {
    return $this->$name;
  } else {
    trigger_error( 'Cannot access protected property CVObject::$' .
                     $name . ' in ' . $trace[0]['file'] . ' on line ' .
                     $trace[0]['line'],
                    E_USER_NOTICE );
  }
}

Моя идея вДело в том, что если вызывающий файл взят из SimpleTest, сделайте свойство доступным для целей тестирования, но если нет, вызовите ошибку.Это позволяет мне сохранять частную собственность, но я могу использовать ее в тестировании, что будет более важно для меня с определенным частным методом, который я собираюсь начать писать.

Итак, мой вопрос, я что-то упустил здесь очень плохо и должен избегать этой техники?

Ответы [ 3 ]

10 голосов
/ 20 февраля 2011

Если вы застряли и просто должны получить доступ к частному / защищенному свойству, чтобы включить тщательное тестирование, по крайней мере, поместите код, который разрешает доступ, в ваш тест или среду тестирования. Внедрение кода только для тестирования в производственный код a) усложняет проект, b) добавляет больше кода, который должен быть протестирован, и c) означает, что код работает по-другому в производственном процессе.

Вы можете использовать метод подкласса Кена для защищенных свойств, но если вам нужен доступ private и вы используете PHP 5.3.2+, вы можете использовать отражение.

function test__Construction_Should_Properly_Set_Tables() {
    $cv = new CVObject( array( 'tables' => $this->standardTableDef ) );
    $tables = self::getPrivate($cv, 'tables');
    $this->assertEqual( $tables, $this->standardTableDef );
}

static function getPrivate($object, $property) {
    $reflector = new ReflectionProperty(get_class($object), $property);
    $reflector->setAccessible(true);
    return $reflector->getValue($object);
}

Обратите внимание, что getPrivate() не будет работать так, как написано для свойств, унаследованных от суперклассов, но это не слишком сложно зациклить иерархию, чтобы найти декларирующий класс.

0 голосов
/ 19 февраля 2011

Быстрое и грязное решение состоит в том, чтобы использовать защищенные (а не частные) методы, а затем тестировать с помощью оболочки, которая делает тестируемые методы общедоступными.

class Foo
{
    protected function bar(){} // should really be private but protected will do
}

class FooTestWrapper extends Foo
{
    public function bar{} { return parent::bar(); } // this is testable
}

Но, как указывает ljank , тестирование частных методов / реализаций может стать кошмаром обслуживания - это, вероятно, означает, что вы выполняете работу, которая должна быть передана другим классам.

0 голосов
/ 19 февраля 2011

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

Чтобы убедиться, что ваши частные (вспомогательные) методы написаны правильно, просто используйте анализатор покрытия кода (пожалуйста, проверьте Инструменты покрытия кода для PHP ) и охватите как можно больше кода с помощью своего тестаслучаи.

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

...