Использование PHPUnit для имитации программного метода, не указанного в тестируемом классе

Использование PHPUnit 3.6 Я пытаюсь протестировать exec () в следующем классе контроллера.Этот метод выполняет две функции:

  1. Определяет имя вызываемого метода на основе существующих свойств объекта и ...
  2. Если определенный метод контроллера является вызываемым, он выполняется, и если нет, метод генерирует исключение

(упрощенный) исходный код выглядит так:

abstract class CLIController extends Controller
{
  /* irrelevant class details here */

  public function exec()
  {
    $action = ! empty($this->opts->args[0])
      ? $this->opts->args[0]
      : $this->default_action;

    if ( ! $action || ! is_callable(array($this, $action))) {
      $msg = 'Invalid controller action specified';
      throw new LogicException($msg);
    } else {
      $this->$action(); // <---- trying to get code coverage on this line!
    }
  }
}

Итак, моя проблема ...

Я не могу понять, как охватить эту часть кода:

} else {
  $this->$action();
}

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

Что может быть ответом ...

  • ??? Возможно, эта строка даже не нуждается в покрытии, потому что она по существу зависит от способности PHP правильно вызывать метод вызываемого класса. Если я успешно проверю, что exec () выдает исключение, когда это должно быть, я знаю, что правильное функционирование рассматриваемой строки зависит от правильного функционирования PHP. Делает ли это недействительной необходимость тестирования в первую очередь ???
  • Если есть способ имитировать абстрактный класс и создать метод с известным именем для добавления к имитируемому классу , это будет решить мою проблему, и это то, что я безуспешно пытался сделать до сих пор.
  • Я знаю, что могу создать дочерний класс с известным именем метода, но я не считаю, что создавать конкретный дочерний класс просто для проверки абстрактного родителя - хорошая идея.
  • Возможно, мне потребуется рефакторинг. Единственное, чего я не хочу делать, - это оставлять дочерние классы для самостоятельной реализации функции exec () .

То, что я пробовал ...

  • Бесполезно использовать некоторые возможности отражения PHP - возможно, это может быть связано с моей собственной неопытностью в отражении, а не его неспособностью справиться с этим случаем.
  • Переход назад и вперед через руководство по PHPUnit и документацию по API. К сожалению, каким бы замечательным ни был PHPUnit, я часто нахожу документацию по API немного легкой.

Я был бы очень признателен за любые советы о том, как лучше всего действовать здесь. Заранее спасибо.

5
задан hakre 1 August 2012 в 07:53
поделиться