Reputation: 21333
Well, I'm new to unit-testing (with phpUnit) and just started to test one class of mine.
Actual constructor looks like this:
/**
* Loads configuration.
*/
function __construct() {
$config =
Kohana::$config->load('koffee');
$this->_table_name = $config->table_name;
$this->_table_columns = $config->table_columns;
}
It basically gets configuration from another file and sets it as protected properties to that object.
Here is how unit-test looks (it's not finished and that's where I need help):
/**
* 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?!
}
The problem is that properties are protected and I cannot access them so easy...
Possible solutions I see at the moment:
Probably this is funny to you, but, as I said, I'm new to unit-tests. Any help much appreciated.
Upvotes: 3
Views: 4556
Reputation: 165
You can try to use ReflectionClass::newInstanceWithoutConstructor
$reflector = new ReflectionClass('Model_Article');
$object = $reflector->newInstanceWithoutConstructor();
Upvotes: 0
Reputation: 198119
Unit-testing is about unit testing. Protected members are not part of the public interface of a unit, which is all you should need to care about when writing unit tests.
You don't test the inner guts of a unit, but that it works as expected.
If you regardless of that want to do such stuff, you can use SerializationDocs, casting to array and ReflectionDocs to inspect protected/private properties of an object or to execute protected/private methods of an object.
See as well: PhpUnit private method testingSO Q&A
Upvotes: 8
Reputation: 1769
You could create a subclass that does expose the data you need and only use it for unit testing.
You could also test the behavior of the class rather than the data. The Model_Article must do something with the table_name and table_columns so test that behavior. For example, if the Model_Article is used to create an html table, then you could set the config values, create the Model_Article, use it to create the html, then assert that it matches a hard coded string like <table title='name'><tr><th>col1</th><th>col2</th</tr></table>
[edit] You could also rely on constructor injection to pass the table_name and table_columns instead of having a hidden dependency on the configuration.
Upvotes: 2
Reputation: 1151
A technique I've used in the past has been to create a Tester class that exposes the appropriate methods to test the object. In this case, Model_Article_Tester
would inherit Model_Article
and expose a get
method. The benefit here is you expose what you need for tests without affecting production code.
Upvotes: 2