Как тестировать контроллеры с помощью CodeIgniter?

У меня есть веб-приложение PHP, построенное с использованием инфраструктуры CodeIgniter MVC. Я хочу протестировать различные классы контроллеров. Я использую Toast для модульного тестирования. У моих контроллеров нет состояния, все, что они обрабатывают, либо сохраняется в сеансе, либо передается на просмотр для отображения. Создание макетного объекта сеанса и проверка правильности его работы просто (просто создайте макет и добавьте его с помощью $ controller-> session = $ mock).

Я не знаю, как работать с представлениями. В CodeIgniter представления загружаются как:

$this->load->view($view_name, $vars, $return); 

Поскольку я не хочу изменять код CI, я мог бы создать макет Loader и заменить оригинал. И здесь проблема, я не могу найти способ получить новый класс из CI_Loader.

Если я не включаю файл system / libraries / Loader.php, класс CI_Loader не определен, и я не могу наследовать его:

 class Loader_mock extends CI_Loader 

Если я действительно включаю файл (используя require_once), я получаю ошибку:

 Cannot redeclare class CI_Loader 

Похоже, что сам код CI не использует require_once по любой причине.

У кого-нибудь есть опыт работы с модульными приложениями, работающими на CodeIgniter?

Изменить: я попытался внедрить реальный объект-загрузчик во время выполнения в класс-макет и перенаправить все вызовы и переменные с помощью __call, __set, __get, __isset и __unset. Но, похоже, это не работает (я не получаю никаких ошибок, хотя, просто нет вывода, т. Е. Пустая страница из Toast). Вот код:

 class Loader_mock { public $real_loader; public $varijable = array(); public function Loader_mock($real) { $this->real_loader = $real; } public function __call($name, $arguments) { return $this->real_loader->$name($arguments); } public function __set($name, $value) { return $this->real_loader->$name = $value; } public function __isset($name) { return isset($this->real_loader->$name); } public function __unset($name) { unset($this->loader->$name); } public function __get($name) { return $this->real_loader->$name; } public function view($view, $vars = array(), $return = FALSE) { $varijable = $vars; } } с class Loader_mock { public $real_loader; public $varijable = array(); public function Loader_mock($real) { $this->real_loader = $real; } public function __call($name, $arguments) { return $this->real_loader->$name($arguments); } public function __set($name, $value) { return $this->real_loader->$name = $value; } public function __isset($name) { return isset($this->real_loader->$name); } public function __unset($name) { unset($this->loader->$name); } public function __get($name) { return $this->real_loader->$name; } public function view($view, $vars = array(), $return = FALSE) { $varijable = $vars; } } 

Related of "Как тестировать контроллеры с помощью CodeIgniter?"

В качестве альтернативы вы можете сделать следующее:

 $CI =& get_instance(); $CI = load_class('Loader'); class MockLoader extends CI_Loader { function __construct() { parent::__construct(); } } 

Затем в вашем контроллере выполните $ this-> load = new MockLoader ().

Мое текущее решение – изменить код CodeIgniter, чтобы использовать require_once вместо require. Вот патч, который я собираюсь отправить разработчикам CI, в случае, если кто-то должен сделать то же самое, пока не примет его:

 diff --git a/system/codeigniter/Common.php b/system/codeigniter/Common.php --- a/system/codeigniter/Common.php +++ b/system/codeigniter/Common.php @@ -100,20 +100,20 @@ function &load_class($class, $instantiate = TRUE) // folder we'll load the native class from the system/libraries folder. if (file_exists(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT)) { - require(BASEPATH.'libraries/'.$class.EXT); - require(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT); + require_once(BASEPATH.'libraries/'.$class.EXT); + require_once(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT); $is_subclass = TRUE; } else { if (file_exists(APPPATH.'libraries/'.$class.EXT)) { - require(APPPATH.'libraries/'.$class.EXT); + require_once(APPPATH.'libraries/'.$class.EXT); $is_subclass = FALSE; } else { - require(BASEPATH.'libraries/'.$class.EXT); + require_once(BASEPATH.'libraries/'.$class.EXT); $is_subclass = FALSE; } } 

Я не могу помочь вам в тестировании, но я могу помочь вам расширить библиотеку CI.

Вы можете создать свой собственный класс /application/libraries/MY_Loader.php внутри /application/libraries/MY_Loader.php .

 <?php class MY_Loader extends CI_Loader { function view($view, $vars = array(), $return = FALSE) { echo 'My custom code goes here'; } } 

CodeIgniter увидит это автоматически. Просто вставьте функции, которые вы хотите заменить в исходной библиотеке. Все остальное будет использовать оригинал.

Для получения дополнительной информации ознакомьтесь с страницей руководства CI для создания основных системных классов .

Я впечатлен кодом, который вы пытаетесь использовать.

Итак, теперь мне интересно, как класс «Крюков» CodeIgniter может быть полезен для вашей проблемы?

http://codeigniter.com/user_guide/general/hooks.html

С уважением, Рейн Грут

Контроллер не должен содержать логику домена, поэтому модульные тесты здесь не имеют смысла.

Вместо этого я бы проверил контроллеры и представления с приемочными испытаниями.