Faster dependency mocking 04

I’m developing a series of classes to create ad-hoc adapter classes wrapping globally defined functions with ease and make dependency mocking faster.

The idea

WordPress themes and plugins will depend, to a greater or smaller extent, from globally defined functions which are not “mockable” at all if not resorting to libraries like runkit or manually redefining and stubbing each one the object under test might come to use.
This problem can be solved “wrapping” the functions used by a plugin or theme classes in an adapter that, as an object, will allow for method mocking and stubbing.
In its most basic form an adapter will modify the code that uses it from

$var = globally_defined_function($value);

to

$var = $this->adapter->globally_defined_function($value);

where the adapter implementation might be as simple as

class Adapter {
    public function __call($function, $args){
        return call_user_func_array($function, $args);
    }
}

Beside the magic method overhead this implementation will also create other problems related to mocking. Ideally an adapter should define any and all methods that will be called on it explicitly to solve both issues. The simple one above would become

class Adapter {

    public function globally_defined_function($value){
        return globally_defined_function($value);
    }

}

Since the whole problem is generated by testing needs I will assume the first contact the classes using the adapter will have with the world will be in a test and the idea is to use those development sessions to create and up-to-date ad-hoc adapter classes defining methods wrapping only and all the functions the plugin/theme/project would access in the global space.

Automate at test time

The target interaction in the test code would be to inject the FunctionsCallsCollector as a dependency in a class using adapters

use tad\DependencyMocking\AdapterClassGenerator as Generator;
use tad\DependencyMocking\FunctionCallsCollector as CollectorAdapter;

class ClassUsingAdaptersTest extends \PHPUnit_Framework_TestCase{

    protected static $jsonFilePath = 'path/to/file.json';
    protected static $adapterFilePath = 'path/to/AdHocAdapter.php';

    /**
     * Will run once before any test runs
     * @beforeClass
     */
    public static function removePreviousAdapter(){
        if(file_exists(self::$adapterFilePath)){
            unlink(self::$adapterFilePath);
        }
    }

    public function setUp(){
        // the CollectorAdapter implements the `tad_Adapters_IFunction`
        // interface
        $this->collectorAdapter = new CollectorAdpater();
        $this->collectorAdapter->_setJsonFilePath(self::$jsonFilePath);
        $this->collectorAdapter->_shouldAppend(true);

        // either in the constructor or with an accessor method the 
        // class allows for the injection of an object implementing
        // the `tad_Adapters_IFunction` interface
        $sut = new ClassUsingAdapters();
        $sut->setAdapter($this->collectorAdapter);
    }

    public testOne(){
        // will call methods wrapping globally defined functions on the
        // adapter
        $this->sut->methodOne();
        ...
    }

    public testTwo(){
        // will call methods wrapping globally defined functions on the
        // adapter
        $this->sut->methodTwo();
        ...
    }

    ... more tests on more methods of ClassUsingAdapter

    /**
     * Will be called after all tests ran
     * @afterClass
     */
    public static function generateAdapter(){
        Generator::constructFromJson(self::$jsonFilePath)
            ->addMagicCall()
            ->setOutputFile(self::$adapterFilePath)
            ->generate();
    }
}

and have it generate, on each run of the test case, a new ad hoc adapter class.

Next

I will be testing the idea and the inner workings more and add a way to “merge” adapter classes if so desired.