Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Alternatives to runkit for intercepting method calls

I have some very test-unfriendly code (to say the least) that I need to test. Refactoring unfortunately is not an option. I have to test the code as it is, without the possibility of changing it.

To do that, I was thinking of intercepting function calls and dynamically change what they do so I can run my tests, as I need some functions and methods to return known values, and I need others that make requests, connect to the database, etc, to stop doing that and return what I need them to return. Is there any way to do this without runkit_method_redefine(), which is preferably not "EXPERIMENTAL" and still maintained? Maybe an alternative to runkit? Maybe a better way?

Edit: will use PHPUnit's test doubles and PHP 5.3.2's features for making private methods accessible, if I need that functionality.

like image 210
rid Avatar asked May 27 '11 15:05

rid


2 Answers

Note: the Test-Helper extension is superseded by https://github.com/krakjoe/uopz

PHPUnit's Test Helper extension (PECL) allows redefiniton/intercepting/stubbing/mocking of hardcoded dependencies with your own implementations:

protected function setUp()
{
    $this->getMock(
      'Bar',                    /* name of class to mock     */
      array('doSomethingElse'), /* list of methods to mock   */
      array(),                  /* constructor arguments     */
      'BarMock'                 /* name for mocked class     */
    );

    set_new_overload(array($this, 'newCallback'));
}

It also allows intercepting the exit statement and instance creation:

  • https://github.com/sebastianbergmann/php-test-helpers

For stubbing and mocking methods you simply use PHPUnit's regular mocking framework. See

  • http://www.phpunit.de/manual/current/en/test-doubles.html

You can also use Mockery with PHPUnit:

  • https://github.com/padraic/mockery

Another option would be to use http://antecedent.github.io/patchwork

Patchwork is a PHP library that makes it possible to redefine user-defined functions and methods at runtime, loosely replicating the functionality runkit_function_redefine in pure PHP 5.3 code, which, among other things, enables you to replace static and private methods with test doubles.

like image 168
Gordon Avatar answered Sep 28 '22 07:09

Gordon


The runkit extension is a perfect solution for your needs. It is proven by years of my personal experience and described in many presentations and articles authored by different authors in the internet.

I can assure you that the runkit_method_redefine function as well as the whole runkit extension is not experimental anymore (documentation hosted on the php.net is obsolete). The up-to-date runkit extension can be found on http://github.com/zenovich/runkit

Sincerely, Dmitry Zenovich

like image 20
Dmitry Zenovich Avatar answered Sep 28 '22 07:09

Dmitry Zenovich