I have an interface I want to mock, and mock the behaviour of one of it's methods.

So I have created a callback that mocks the behaviour very simply.

This test passes if I create a new object that is based on this interface, but I would like to mock the interface.

The mocked setUp method is being called fine, and calling getVar('testing') in my callback returns the value. However my assertion fails, because that value isn't available.

It seems that you can't do this in PHPUnit? Unless I am being stupid.

Brief explanation of the code flow; The code in "getVar" calls a method which calls the "setUp" on the added plugin. When it calls "setUp" it passes in "$this". It is $this I am expecting to be passed by reference and which works with a "real" object.

class DefaultRendererTest extends \PHPUnit_Framework_TestCase
{

    public function testSetGetVar()
    {
        $theme = $this->getMock('ThemeInterface');

        $plugin = $this->getMock('PluginInterface');
        $plugin->expects($this->once())
          ->method('setUp')
          ->will($this->returnCallback(function($r){

              $r->setVar('testing', "fooBar");

        }));

        $renderer = new DefaultRenderer($theme, null);
        $renderer->addPlugin($plugin);
        $this->assertEquals('fooBar',$renderer->getVar('testing'));
    }
}

For info here is the interface, the DefaultRenderer implements a RendererInterface

interface PluginInterface
{
    function setUp(RendererInterface $renderer);
}

Comments

Looks perfectly valid to me. Did you check if $r and $renderer are actually references to the same object? Though, I don't see a reason why they shouldn't. Maybe there is a bug in setVar() or getVar()?

Written by tobyS

Accepted Answer

OK, out of interest, I tracked down the issue. It seems that PHPUnit automatically clones the parameters before the actual invocation takes place. I don't see a real reason for this, but maybe there is one. Taking a look at Framework/MockObject/Invocation/Static.php, there is only a single way how you can avoid this (on basis of the built in mock code): Implement a private __clone() method in the DefaultRenderer.

I'd also suggest you ask on IRC or the PHPUnit mailinglist about this behaviour or the mock object library.

Written by tobyS
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki