PHP - Alternatives to runkit for intercepting method calls

故事扮演 提交于 2019-12-21 16:47:27

问题


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.


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/6154412/php-alternatives-to-runkit-for-intercepting-method-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!