Unit test protected in PHP

So, I admit it, I like to know that my utility functions are working right. Unfortunately, most of the time, I try to keep my functions to only a few lines and as stateless as possible. And while it doesn’t necessarily hurt anything to have some stateless method accessible publicly, it often does not make sense to do so. And while I do admit that the unit test generally should be reserved for public method i/o, I think it best to test everything possible.

To that end, I wrote a simple function which will let you test the protected variables/functions:

function unlockClass($c)
{
	$ev = <<<'HER'
{
	public function __call($name, $args)
	{
		$name = substr($name, 1);
		if(!is_callable(array($this,$name)))
			throw new Exception("Cannot call $name");
		return call_user_func_array(array($this,$name),$args);
	}
 
	public function __get($name)
	{
		$name = substr($name, 1);
		return $this->$name;
	}
 
	public function __set($name, $val)
	{
		$name = substr($name,1);
		$this->$name = $val;
	}
}
HER;
	$ev = ("class Unlocked_$c extends $c $ev");
	//echo $ev; 
	eval($ev);
}

Basically, to address a protected field, simply prepend some character before the name (I generally use an underscore).

Eg:

class Foo{
    protected $bar = 1;
    protected doSomething(){ echo 'something';}
}
 
unlockClass('Foo');
$f = new Unlocked_Foo();
echo $f->_bar; // 1
$f->_doSomething(); // something

Unfortunately, there is no way to access private fields (and there shouldn’t be), but it isn’t really a good idea to have too many of those anyway.

This entry was posted in PHP. Bookmark the permalink.

One Response to Unit test protected in PHP

  1. Pingback: An elegant defense of strong typing | Unusual Subroutines | The Professional Blog of C. Allen-Poole, Web Developer

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>