1

Possible Duplicate:
PHPUnit Mock Objects and Static Methods
unit testing and Static methods

I'm using PHPUnit 3.6.10 and I can't seem to find a good example of mocking static methods in the documentation. Specifically, I have a class A with method a() -- call it A->a() -- which calls B::b() which I need to mock the return value of.

class A {
    function a() {
        return B::b();
    }
}

class B {
    static function b() {
        return 5;
    }
}

The test function for a() should look like below:

class A_Test {
    function test_a() {
        // what should the code look like here?
    }
}

Since we're purely testing that A->a() returns B::b(), we're not concerned with how B::b() works, so we can mock the return value of B::b() (say, to return 'foo') and check that 'foo' is returned when we call A->a(). How can this be done?

Community
  • 1
  • 1
arimbun
  • 3,885
  • 2
  • 19
  • 16
  • Is there a way to write the test without having to refactor the code at all? – arimbun Aug 28 '12 at 07:05
  • you dont have to refactor anything. you just set the expectation for B with staticExpects. – Gordon Aug 28 '12 at 07:08
  • 2
    Static method calls are inherently difficult to test, and they're often a code smell that you've got a tight coupling between the class under test and the class that's providing the static method. For these reasons, statics are often frowned upon these days. – GordonM Aug 28 '12 at 07:16
  • To use `staticExpects` here, `A::a` would have to call `MockB::b`. Static expectations are designed for when a method calls a static method on its own class, e.g., `self::foo`. Changing that call to `static::foo` allows you to mock it. – David Harkness Aug 28 '12 at 08:06
  • @DavidHarkness So you are saying that it is impossible to mock the call to B::b() from A->a()? Is there a way to test A->a() then, without having to refactor the code? If not, what solutions do you propose? – arimbun Aug 28 '12 at 23:06
  • Of all the examples given, it seems that you can only mock static methods if the caller is also within the same class. – arimbun Aug 28 '12 at 23:10
  • @arimbun - Yes, that's what I'm saying. Your only options are to isolate the test for `A` in a separate process so you can define a stub `B` or refactor the code. – David Harkness Aug 29 '12 at 01:50

0 Answers0