Page 1 of 1

Mocking functions with parameters passed by reference

Posted: Mon Dec 21, 2009 7:37 am
by grarfloup
Hi there,

We've started unit testing our application with PHPUnit 1 month ago (meaning we're doing "test after", unfortunately).
The last trouble I'm running into is that there doesn't seem to be a way to mock values returned via
parameters passed by-reference.

For example, I can't mock the $user returned by getUser(&$user, $userId), where the first parameter is used
to return the user (the function's return type being a status code).
You can't do this with returnCallback() since values assigned to the parameters passed by ref. are lost...

Has anybody ran into this trouble and already found a workaround ?
(for now mine is using hand crafted stubs, but this becomes cumbersome very quickly)

Thanks in advance!

Re: Mocking functions with parameters passed by reference

Posted: Mon Dec 21, 2009 9:09 am
by Jenk
Can you post the test that is problematic? I'm not a user of phpunit but I reckon I can come up with a solution :)

Re: Mocking functions with parameters passed by reference

Posted: Mon Dec 21, 2009 9:28 am
by grarfloup
Hehe ok, I'll try to put up a simple example that will isolate the problem clearly... and post it here.

Re: Mocking functions with parameters passed by reference

Posted: Thu Dec 24, 2009 12:09 pm
by josh
Does this isolate the problem?

Code: Select all

 
<?php
class myMock
{
    function returnReference( $a )
    {
        return $a;
    }
}
class TestPHPUnit extends PHPUnit_Framework_TestCase
{
    function testReal()
    {
        $a = new stdClass;
        $b = new stdClass;
        $this->assertFalse( $a === $b, 'we understand how references work' );
        $this->assertTrue( $a === $a, 'we understand how references work' );
        
        $mockObject = $this->getMock( 'myMock' );
        $mockObject->expects( $this->any() )->method( 'returnReference' )->will( $this->returnArgument(0) );
        
        $c = $mockObject->returnReference( $a );
        $this->assertTrue( $a == $c, 'equals should work' );
        $this->assertTrue( $a === $c, 'references should work' );
    }
    
    function testMock()
    {
        $a = new stdClass;
        $b = new stdClass;
        $this->assertFalse( $a === $b, 'we understand how references work' );
        $this->assertTrue( $a === $a, 'we understand how references work' );
        
        $mockObject = new myMock; // use a real object
        $c = $mockObject->returnReference( $a );
        $this->assertTrue( $a == $c, 'equals should work' );
        $this->assertTrue( $a === $c, 'references should work' );
    }
}
Both of these tests should pass. I am submitting a feature enhancement request. http://www.phpunit.de/ticket/976

Re: Mocking functions with parameters passed by reference

Posted: Thu Dec 24, 2009 7:49 pm
by josh
Mine was a duplicate and someone already wrote this patch. http://www.phpunit.de/ticket/940