Bastian's Blog

Bastian's Blog

Info | HTML | Text | RSS

Testing the invisible with proxy-object

A story from the past

Almost three years ago in 2008, I sat together with my fellow friend and former collegue (Thomas Weinert). As we already knew, it is possible to expose protected members and methods by creating a proxy class extending the original class and just override the method to be exposed.

<?php class TuxProxy extends Tux { public function Puffy() { return parent::Puffy(); } }

But this always ended up in a huge amount of proxy classes; we at least needed one for each class to expose every protected method. As you might have noticed I am not talking about private methods and there was not one word about invisible members. yeah, we had to skip those in our handwritten proxies. PHP does not allow to override private methods nor members. Worse, to inherit protected members, they had to be overridden by a public member loosing their original value. So we ended up with a huge mess of inherited classes, exposed methodes, and members not reflecting their initial content. Hillarious!

<?php class TuxProxy extends Tux { public $os = 'this is a copy of the original content.'; public $items = array( 'there', 'is', 'no', 'fun', 'in', 'duplicating', 'content' ); public $severity = 'ANd risky in ters of erros, too!'; // suppress the original constructor + public function __construct() […] + public function Puffy() […] + public function Another() […] + public function Huge() […] + public function Pile() […] + public function Of() […] + public function Collapsed() […] + public function And() […] + public function Exposed() […] + public function Methods() […] }

Speaking of reflection. Unfortunately Manuel Pichler probably did not spend a minute thinking about his future invention and he was definetly not aware of the fact that the staticRelfection API would have saved us a lot of work in the first place. So we needed to find another source of inspiration … the phpunit-mock-object (how it is called today). Inspired by the idea of generating the whole thing was a hughe step and the birth of the idea to write the little library announced by this article, the proxy-object.

What is this proxy-object everyone is talking about?

The proxy-object library extends your PHPUnit framework with the ability to create a proxy object on demand; like you already know from using the phpunit-mock-object.

<?php […] use \lapistano\ProxyObject; $proxy = new ProxyObject(); $proxiedClass = $proxy->getProxy('\\Tux'); […]

Similar to its role model, the proxy object provides a fluent interface to make it as easy as it could be to configure the object to be created.

<?php […] use \lapistano\ProxyObject; $proxy = new ProxyObject(); $proxiedClass = $proxy->getProxyBuilder('\\Tux') ->setProperties(array('items')) ->setMethods(array('Puffy')) ->getProxy(); […]

The example above shows how to expose members and methods to be accessed from a test. Even invisible members will contain their original values. If you do not set any methods nor members to be exposed, the library assumes that you want to expose every member and method.

But wait! What about private methods and members? Before this library got published it went through several stages of evolution. Some day I learned about Reflection API and decided to use it to expose private members and methods. yeah, I know some of you will tell me, that exposing private members or methods is a bad practice, and I agree. Seriously! But sometime you have to get some information about your SUT (System Under test) you cannot even reach using PHPUnits "assertAttribute*" assertions.

So much for a short introduction of the proxy-object. If I caught your attention with this, just fork it from github and send me some feedback.

If you like this article, I'd be very pleased if you'd flattr me.



Add new comment

Fields with bold names are mandatory.