====== Mocking Functions in Simple Test ====== When dealing with external projects that you either want to re-use parts of or refactor, being able to write unit tests is often a big problem, especially if it's written in procedural code like; function aFunctionIWantToTest($foo) { $foo = aFunctionIDontWantToTest($foo); } function aFunctionIDontWantToTest($foo) { global $conf; // aaargh! if ( $conf['reevaluateMeEveryTime'] ) { doSomethingPainful($foo); } else { ohGodAndAnotherFunction($foo); } } Being able to "mock" ''aFunctionIDontWantToTest'' in a similar manner to [[http://www.lastcraft.com/mock_objects_documentation.php|Mock Objects]] would be a big help. Brought this up a while back [[http://sourceforge.net/tracker/index.php?func=detail&aid=1315670&group_id=76550&atid=547458|here on the SimpleTest feature tracker]] and sent a [[http://sourceforge.net/mailarchive/forum.php?thread_id=8853618&forum_id=34779|mail today]] to the SimpleTest list with an initial implementation.((Note I'm //not// dumping this here to add pressure to include this in SimpleTest - there are good reasons why SimpleTest shouldn't offer this which I can understand - but not sure if the message to list included my attachment plus think this is a valid "unsupported" addition to SimpleTest which people can use at their own risk)). After discovering [[http://www.php.net/apd|APD's]] (at least in the old 0.4 version I was using) [[phpfn>rename_function]] does very wierd things settled on [[http://www.php.net/runit|runkit]] as the tool to help "mock" a function, which so far seems to work fine. Be warned you can rename //anything// including pre-defined PHP functions - lots to room to shoot yourself in the foot. Example use (testing [[http://dev.splitbrain.org/reference/dokuwiki/nav.html?inc/html.php.source.html#l284|this]]); class html_hilight_test extends UnitTestCase { function testHighlightTwoWords() { MockFunction::generate('unslash'); $html = 'Foo bar Foo php Foo'; MockFunction::setReturnValueAt(0,'unslash','bar'); MockFunction::setReturnValueAt(1,'unslash','php'); MockFunction::expectCallCount('unslash',4); $this->assertPattern( '/Foo bar<\/span> Foo php<\/span> Foo/', html_hilight($html,'bar php') ); MockFunction::restore('unslash'); } } Basically the methods are all the same as normal SimpleTest mock objects but are called statically via the the MockFunction class. **Note:** you must call ''MockFunction::restore()'' yourself when you're finished, otherwise you'll have mock functions "lying around", which may lead to //very// hard to debug problems when running other tests Source code available here: {{develop:mockfunctions.tar.gz}}