codework
codework

Reputation: 66

How can I mock a static function with phpunit 4.6.6 and later

I know staticExpects is deprecated as of PHPUnit 3.8 and will be removed completely with later versions. But in our project, using static function everywhere.So,It's a big problem to make phpunit.And In our dev,phpunit version is 4.6.6,I can not back to 3.8. My question is how can I do like staticExpects? code:

class A {
    public static function staticfun(){
       //dosomething....     
    }
}
class B {
    public static function callA(){
       A::staticfun();
    }

}

class TestA extends PHPUnit_Framework_TestCase{
    public function test(){
        //I want to mock staticfun()
        B::callA();

    }
}

Upvotes: 1

Views: 583

Answers (2)

user3942918
user3942918

Reputation: 26413

To do this you'd need to use an extension like uopz that allows you to redefine functions and methods at runtime.

In your test class you'd add something like:

public static function setupBeforeClass()
{
    uopz_backup("A", "staticfun");
    uopz_function("A", "staticfun", function () {
        // do something else
    });
}

public static function tearDownAfterClass()
{
    uopz_restore("A", "staticfun");
}

This'll:

  • back up the original method
  • redefine it as the given closure
  • restore the original when the tests in the class are complete

Upvotes: 1

Sven
Sven

Reputation: 70933

You can, in a general case, not mock static function calls. Don't use static calls if you intend to test your software with mocks. You can try and fiddle with evil tricks, but this usually is a huge pain.

You probably didn't read the documentation for the staticExpects feature of PHPUnit thoroughly. It does not do what you need. Sebastian implemented that feature in PHPUnit 3.5, but it didn't work as he was intending, because people didn't understand its limitations. So it was removed again in 3.8.

Face the fact that you created untestable software by using static calls. Start to throw them out and improve the testability of the software that way. It is painful and will cost time, but it is the only way.

Upvotes: 0

Related Questions