5

I have a unit test that I am writing and have run into an annoying problem... Let's say I have the following function I am testing:

public function functionToTest(array &$data, parameter2)
{
    // perform some action on the array that is being passed in by reference
}

Now, when I attempt to call this function in my unit test, I would do something like this:

public function testMyFunction()
{
    $data = array('key1' => 'val1');

    $mockOfClass = $this->getMockBuilder('ClassName')
        ->disableOriginalConstructor()
        ->setMethods(array('method1', 'method2')) // My function to test is NOT in this list 
        ->getMock();

    $this->mockOfClass->functionToTest($data, true);

    // Perform assertions here
}

However, I receive the following error message:

Parameter 1 to ClassName::addNewFriendsToProfile() expected to be a reference, value given

This seemed very strange to me. First of all, I'm just passing an array by reference, so it it shouldn't have a problem with this. Secondly, Why parameter 1? Doesn't it mean parameter 0? Then, I tried changing the call to the following:

$this->mockOfClass->functionToTest(&$data, true);

After making this change, it works fine. Unfortunately, it also produces the following warning:

Call-time pass-by-reference has been deprecated in /PathToFile on line xxx

I do not encounter this error when running the actual code. It only throws this error in the unit test. Also, I need to use the mock as there are methods in the class I am mocking; So I can't simply create a new instance of the class and call the method that is being tested. Is there any way I can get around this?

Will Johnson
  • 225
  • 2
  • 13
  • 1
    Related? http://stackoverflow.com/questions/5170747/pass-by-reference-in-a-callback-when-mocking-in-phpunit – Tim Lytle Jun 11 '12 at 01:51
  • Thank you Tim, this is very helpful. It looks like the issue is related to each parameter being cloned in PHPUnit. – Will Johnson Jun 15 '12 at 11:17

1 Answers1

3

It turns out that PHPUnit clones each of the parameters that are being passed in (Thanks Tim Lytle for pointing me to this source: Pass by reference in a callback when mocking in PHPUnit). This is what causes the error if the array is passed in without a reference at call-time in the unit test. Luckily, the solution is simple. Instead of passing the array by reference, I pass in the array by value and return the array.

before:

public function someFunction(array &$myArray)
{
    $myArray[] = 'new val';
}

after:

public function someFunction(array $myArray)
{
    $myArray[] = 'new val';

    return $myArray;
}
Community
  • 1
  • 1
Will Johnson
  • 225
  • 2
  • 13