Usually you just donβt check or scoff at directyβs personal and protected methods.
What you want to test is the public API of your class. Everything else is an implementation detail for your class and should not break your tests if you change it.
It also helps you when you notice that βyou cannot get 100% coverage of the code,β because you may have code in your class that you cannot execute by calling the open API.
Usually you do not want to do this
But if your class looks like this:
class a { public function b() { return 5 + $this->c(); } private function c() { return mt_rand(1,3); } }
I see the need to want to mock c (), since the "random" function is a global state, and you cannot check it.
"clean? / verbose? / overcomplicated-maybe? / i-like-it-usually" Solution
class a { public function __construct(RandomGenerator $foo) { $this->foo = $foo; } public function b() { return 5 + $this->c(); } private function c() { return $this->foo->rand(1,3); } }
now you no longer have to mock "c ()", since it does not contain any globals, and you can test them well.
If you do not want to do or cannot remove the global state from your private function (bad reality or the definition of bad can be different), you can check for mockery.
// maybe set the function protected for this to work $testMe = $this->getMock("a", array("c")); $testMe->expects($this->once())->method("c")->will($this->returnValue(123123));
and run your tests against this layout as the only function you take out / mock is "c ()".
To quote the book Pragmatic Unit Testing:
βIn general, you donβt want to break encapsulation for the sake of testing (or, as your mother said,β do not expose your privates! β). In most cases, you should be able to test the class using your public methods. If there is significant functionality that is hidden behind with private or secure access, this may be a warning sign that another class is trying to exit there. "
A few more: Why you don't want test private methods.