PHPUnit’s getMock($classname, $mockmethods) creates a new object based on the given class name and lets me change/test the behavior of the methods I specified.
I long for something different; it’s changing the behavior of methods of an existing object – without constructing a new object.
Is that possible? If yes, how?
When thinking about the problem I came to the conclusion that it would be possible by serializing the object, changing the serialized string to let the object be instance of a new class that extends the old class plus the mocked methods.
I’d like some code for that – or maybe there is such code already somewhere.
While it would certainly be possible to create the to-be-mocked object again, it’s just too complicated to do it in my test. Thus I don’t want to do that if I don’t really really really have to. It’s a TYPO3 TSFE instance, and setting that up once in the bootstrapping process is hard enough already.
Let me start of by saying: Welcome to the dark side of unit testing.
Meaning: You usually don’t want to do this but as you explained you have what seems to be a valid use case.
runkit
What you can do quite easily, well not trivial but easier than changing your application architecture, is to change class behavior on the fly by using runkit
runkit::method_add
and after the test to a method_remove and the rename again. I don’t know of any framework / component that helps you with that but it’s not that much to implement on your own in a
UglyTestsBaseTest extends PHPUnit_Framework_TestCase.Well…
If all you have access to is a reference to that object (as in: The
$xin$x = new Foo();) i don’t know of any way to say: $x, you are now of typeSomethingElseand all other variables pointing to that object should change too.I’m going to assume you already know things like testing your privates but it doesn’t help you because you don’t have control over the objects life cycle.
The php test helpers extension
What also might help you out here is: Stubbing Hard-Coded Dependencies using the php-test-helpers extension that allows you do to things like Intercepting Object Creation.
That means while your application calls
$x = new Something();you can hack PHP to make it so that$xthen contains an instance ofYourSpecialCraftedSomething.You might create that classing using the PHPUnit Mocking API or write it yourself.
As far as i know those are your options. If it’s worth going there (or just writing integration / selenium tests for that project) is something you have to figure out on your own as it heavily depends on your circumstances.