1

Aren't mocks supposed to replace methods and their parameters?

I don't understand how this works, I copy-paste examples but i run into trouble on every single example that should work out of the box..

The problem i run into is that the methods do not have their parameters removed, so if a method has a certain dependency as a parameter, i HAVE to pass it to the mock's method too..

The manual even says that by default all methods are replaced by empty methods that return null.

I'm using 5.7(php 5.6)

class SomeClass
{
    public function doSomething(\Exception $e)
    {
        // Do something.
    }
}

class StubTest extends TestCase
{
    public function manualExampleDoesntWork()
    {
        // Create a stub for the SomeClass class.
        $stub = $this->createMock(SomeClass::class);

        // Configure the stub.
        $stub->method('doSomething')
             ->willReturn('foo');

        // Calling $stub->doSomething() will now return
        // 'foo'.
        $this->assertEquals('foo', $stub->doSomething());
    }

    public function ...
    {
        // Should be enough, doesnt work
        $stub = $this->createMock(SomeClass::class);
        $stub->doSomething(); // error

        // Neither
        $stub = $this->createMock(SomeClass::class);
        $stub->method('doSomething')
             ->withAnyParameters()
             ->willReturn('foo');
        $stub->doSomething(); // error

        // Same for manually building with the mockbuilder..
    }
}

Results in: Argument 1 passed to Mock_***95::doSomething() must be an instance of Exception, none given

This is just one example, I've tried every possible variation of creating mocks, all results in me not being able to replace the parameters..

Maxim
  • 52,561
  • 27
  • 155
  • 209
Alt-rock ninja
  • 165
  • 1
  • 13

1 Answers1

1

It is about method overloading / overriding. PHP does not support this stuff same way as, say, C++ or Java do -- meaning you can't declare methods having same name and different arguments lists either in the scope of current class or further in inheritance chain. Methods signatures must stay the same. One exception is __construct which is overridable with different signature. Should be also mentioned that PHP does have overloading concept but it is a bit different idea. You can read more here and here.

Concerning your particular example all said above means you must call doSomething with either instance of Exception class or with a stub for Exception because the doSomething method of of SomeClass 's stub still has same signature as authentic SomeClass. Also another option could be declaring it as public function doSomething(\Exception $e = NULL).

The implementation of the doSomething method in SomeClass mock is really empty by default -- till you configure it.

Community
  • 1
  • 1
xmike
  • 1,029
  • 9
  • 14
  • You surely should not be. There are always things out there that happen differently than we think or expect )) – xmike Mar 02 '17 at 09:38