1

I am trying to write tests for a Laravel application and I can't seem to figure out how to test static methods that call other static methods from the same class. Say I have this class:

class Foo
{
   public static function foo()
    {
        return !self::bar();
    }

    public static function bar()
    {
        $trueOrFalse = [true, false];
        $key = array_rand($trueOrFalse);
        return $trueOrFalse[$key];
    }
}

I want to test that Foo::foo() returns the opposite of Foo::bar(). So what I would like to do is have a mock that would return a precise value in place of Foo::bar().

I can do that if I write this in my test file

class FooClassTest extends TestCase
{
public function testFooMethod()
    {
       $mock = Mockery::mock('alias:' . Foo::class);
       $mock->shouldReceive('bar')->once()->andReturn(true);

       //assertion

But then, when I write my assertion: $this->assertEquals(false, Foo::foo()); , I get the error "Method Foo::foo() does not exist on this mock object".

That makes sense, since class Foo has been replaced with $mock throughout the app because of the "alias:" flag. Using "overload:" leads to the same error message. And partial mocking doesn't work either.

Is there any way to test such class methods using mocking? Or an alternative to mocking?

  • take a look at this: https://stackoverflow.com/questions/5988616/phpunit-mock-method-multiple-calls-with-different-arguments – Jack Apr 05 '23 at 14:25
  • @Jack what has that question to do with the author question? – matiaslauriti Apr 05 '23 at 16:00
  • I think it is not possible to do what you are trying to do, but try this, instead of `self::bar()` use `static::bar()` and let us know if it worked – matiaslauriti Apr 05 '23 at 16:11
  • 1
    @matiaslauriti Many thanks! Using `static::bar()` works, but with a twist: the assertion must be like so `$this->assertEquals(false, $mock->foo())`, instead of `$this->assertEquals(false, Foo::foo())`. I did find a workaround that allowed me to do the tests, but your solution is much more elegant! Much appreciated! – Radu Raileanu Apr 06 '23 at 07:21
  • @RaduRaileanu glad to be of help! Rememeber that `static` resolves to the late binding, so if Mockery gets in the middle, using `static` will resolve to whatever Mockery is extending, using `self` will 100% resolve to the same class, preventing this from working – matiaslauriti Apr 06 '23 at 16:36

0 Answers0