With PHPUnit and PHP >= 5.3 it is possible to test protected methods. The following page at stackoverflow outlined the best practice on it:
"Best practices to test protected methods with PHPUnit"
protected static function callProtectedMethod($name, $classname, $params) {
$class = new ReflectionClass($classname);
$method = $class->getMethod($name);
$method->setAccessible(true);
$obj = new $classname($params);
return $method->invokeArgs($obj, $params);
}
To test public methods on abstract classes is easy with PHPUnit. To test protected methods on normal classes is easy with approach above. To test protected methods on abstract classes must be possible somehow...
I know PHPUnit derives abstract classes and "implements" abstract methods in a concrete class and fires the tests against that concrete class - but i do not know how to integrate that into the approach above to have a callProtectedMethodOnAbstractClasses().
How are you doing such tests?
PS: The question is NOT about the truth of testing protected methods (see: white-, gray- and blackbox-testing). The need of testing protected methods depends on your test strategy.
Since you are asking for a 'best practice' I'll take a different approach to answer:
Just because you can doesn't mean you should.
You want to test that a class works. That means that all the functions you can call on it (everything public) return the right values (and maybe call the right functions on objects passed in) and nothing else.
You don't care how this is implemented in the class.
Imho it is even hurting you to write test for anything non-public for two big reasons:
Writing tests takes longer as you need more and refactoring also takes longer. If you move around code in a class without changing its behavior you shoudn't be required to update its tests. The tests should tell you that everything still works!
If you write a test for every protected method you loose one inherit benefit from the code coverage report: It won't tell you which protected functions aren't call anymore. That is (imho) a bad thing because you either don't test all the public methods correctly (why is there a method that isn't called if you test every case?) or you really don't need that method anymore but since it's "green" you don't give it a second thought.
So: Just because the testing of protected and private attributes and methods is possible does not mean that this is a "good thing".
http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
...->setAccessible()
is fine for normal methods
for abstract stuff use ...->getMockForAbstractClass()
But please do so only if it is really necessary.
A protected method in an abstract class will get tested by testing the public api of its children anyway with my arguments from above applying.