Parody is an extremely simple library that can be used to mimic classes and objects as well as provide working results for method calls (both object and static), getting properties, instantiating objects, etc. It uses sequential method chaining to make defining class structures and operation extremely quick.
This is most useful for testing.
include 'Jest.php';
include 'Mime.php';
Obviously you will have to potentially change the name/location of the files, but the key point above is that Jest
should be included before Mime
. Jest and Mime exist in the Dotink\Parody
namespace, so if you're using namespaces in the surrounding context you may wish to alias/import.
namespace Vendor\Project {
use Dotink\Parody;
}
All examples that follow assume the Parody
namespace is available.
Parody\Mime::define('Vendor\Project\Class');
The example above shows the simplest way to define a class. Using any definition based methods on Mime
, you should keep in mind that you should always provide the full namespace however, you should not use the preceding \
as all are assumed to be rooted in the global namespace.
You can use the extending()
method to provide a parent class to the defined class.
Parody\Mime::define('Vendor\Project\Class')
-> extending('Vendor\Project\BaseClass');
Using the extending method changes the chaining context to that class, so to create a whole chain of inheretance you can do the following.
Parody\Mime::define('Vendor\Project\Class')
-> extending('Vendor\Project\ParentClass')
-> extending('Vendor\Project\GrandParentClass')
Using the implementing()
method you can make defined classes implement arbitrary interfaces.
Parody\Mime::define('Vendor\Project\Class')
-> implementing('Vendor\Interfaces\CustomInterface')
-> extending('Vendor\Project\BaseClass')
-> implementing('Vendor\Interfaces\BasicInterface');
The above example shows the creation of a class implementing the CustomInterface
which extends a BaseClass
implementing BasicInterface
. As such, The original Class
would respond as implementing both interfaces, and also would identify as a subclass of BaseClass
.
You can implement more than a single interface directly on one class by passing multiple arguments to implementing()
.
Traits are done similar to interfaces, except they are defined with the using()
method.
Parody\Mime::define('Vendor\Project\Class')
-> using('Vendor\Traits\SharedFunctionality');
Once classes have been defined you can begin creating object instances of them or define certain properties, method calls, and their respective responses. It is also possible to register a function to define these things for future instantiations.
Parody\Mime::create('Vendor\Project\Class')
-> onCall('method') -> give('response')
-> onGet('booleanProperty') -> give(TRUE);
The Mime::create()
method creates an internal object instance of the class requested. This class, regardless of how many parent classes it has is inevitably a child of Jest
. Jest
objects are very simple objects which are manipulated by Mime
s to make parody possible.
You can get the Jest
object by using the resolve()
method.
$jest = Parody\Mime::create('Vendor\Project\Class')
-> onCall('method') -> give('response')
-> onGet('booleanProperty') -> give(TRUE)
-> resolve()
You can then use the Jest
object to call the methods or get the properties you established.
if ($jest->booleanProperty) {
echo $jest->method(); // This would print 'response'
}
Jest
s should not be taken the wrong way, but inevitably you will have to deal with arguments and vary your responses depending on what those are. It's possible to expect()
them.
$jest = Parody\Mime::create('Vendor\Class\Project')
-> onCall('method') -> expect('argument one') -> give('response one')
-> onCall('method') -> expect('argument two') -> give('response two')
-> resolve();
Now we're ready for some back and fourth!
if ($jest->method('argument one') == 'response one') {
echo 'I really wanted ' . $jest->method('argument two');
}
The above will output the string 'I really wanted argument two'.
It doesn't matter how a method is called:
if (Vendor\Class\Project::method('argument one') == $jest->method('argument one')) {
echo 'So the parody is useful for static dependencies too.';
}
For those who don't always do new
things at the right time, you may be worried that Parody won't do much for your non injected dependencies. But it can:
Parody\Mime::create('Vendor\Class\Project')
-> onNew(function($mime) {
$mime->onCall('method')->give('results');
});
We could even fall a-sleep()
for 10 minutes at this point and then do the following...
$non_injected_dependency = new Vendor\Class\Project();
echo '... and still get our ' . $non_injected_dependency->method();
Or in other words, '... and still get our results'.
Mime
s use Jest
s to conduct Parody
.