2011-12-27 4 views
3

Ну, я новичок в модульном тестировании (с phpUnit) и просто начал тестировать один класс.Как проверить конструктор, который устанавливает защищенные свойства?

Actual конструктор выглядит следующим образом:

/** 
* Loads configuration. 
*/ 
function __construct() { 

    $config = 
     Kohana::$config->load('koffee'); 

    $this->_table_name = $config->table_name; 
    $this->_table_columns = $config->table_columns; 

} 

Это в основном получает конфигурацию из другого файла и устанавливает его в качестве защищаемых свойств к этому объекту.

Вот как блок-тест выглядит (это не закончена, и где мне нужна помощь):

/** 
* Tests that config is loaded and correct. 
*/ 
function testConfigIsLoadedAndCorrect() { 

    $object = new Model_Article(); 

    $config = Kohana::$config->load('koffee'); 

    // Compare object's **protected** properties to local `$config`. How?! 

} 

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

Возможные решения я вижу на данный момент:

  1. Изменение видимости свойств (я не люблю это),
  2. Add, так называемый, «GETT ers "на тест класса I - не unit-test (мне это не нравится);

Возможно, это смешно для вас, но, как я уже сказал, я новичок в модульных тестах. Любая помощь очень ценится.

+0

Вы не написали *, что * вы на самом деле хотите, чтобы проверить и * почему * вы думаете, есть проблема. – hakre

+0

Я хочу сравнить свойства ** объекта ** объекта с локальным '$ config', как указано в тесте. – daGrevis

ответ

8

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

Вы не проверяете внутренние кишки устройства, но это работает так, как ожидалось.

Если вы независимо от того, что хотите делать такие вещи, вы можете использовать Serialization­Docs, casting to array и Reflection­Docs инспектировать защищены/частные свойства объекта или для выполнения защищенных/частные методы объекта.


Смотрите так же:PhpUnit private method testingSO Q&A

+2

(* related *): ['Stackoverflow: phpunit-private-method-testing'] (http://stackoverflow.com/questions/5937845/phpunit-private-method-testing/5937899#5937899) - Тот же общий ответ, еще несколько примеров кода и мотивации. +1 – edorian

+0

@edorian: Спасибо, что оставили ссылку, ваше превосходное знание PHPUnit очень ценится. – hakre

2

Техника, которую я использовал в прошлом, заключалась в создании класса тестера, который предоставляет соответствующие методы для проверки объекта. В этом случае Model_Article_Tester наследует Model_Article и выставляет метод get. Преимущество здесь в том, что вы раскрываете то, что вам нужно для тестов, не влияя на производственный код.

+0

Спасибо. Это похоже на один из способов. – daGrevis

2

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

Вы также можете проверить поведение класса, а не данные. Article_Article должен что-то делать с таблицей_имя и table_columns, чтобы проверить это поведение. Например, если Model_Article используется для создания таблицы html, вы можете установить значения конфигурации, создать Model_Article, использовать ее для создания html, а затем утверждать, что она соответствует строкой с жесткой кодировкой, например <table title='name'><tr><th>col1</th><th>col2</th</tr></table>

[edit ] Вы также можете полагаться на инъекцию конструктора, чтобы передать имя_таблицы и table_columns вместо того, чтобы иметь скрытую зависимость от конфигурации.

+0

Можете ли вы привести мне пример инъекции конструктора, пожалуйста? – daGrevis

+1

Все параметры, необходимые в конструкторе, являются параметрами конструктора: 'function __construct ($ table_name, $ table_columns)'. Затем служба-создатель может создать экземпляр нужного класса с введенной конфигурацией без необходимости использования класса, чтобы узнать, как выполняется настройка, и создателю узнать, какие параметры доступны для конфигурации. – hakre

+0

Это означает, что мне нужно загрузить эту конфигурацию отдельно от класса, а затем просто передать ее конструктору ('new Model_Article ('x', 'y')')? – daGrevis

Смежные вопросы