Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit: get arguments to a mock method call

I'm currently working on a project that stores sensitive data, and must therefore be able to erase them on request.

I'd like to test that my entity (patient) is saved to the database with a null phone number. First idea to do that: get the argument passed to PatientDao::savePatient(PatientModel $patient), and have a look at its phoneNumber attribute.

So here is the PatientDao interface:

interface PatientDao {
    function savePatient(PatientModel $patient);
}

And the code in my test file:

$this->patientDao                    // This is my mock
            ->expects($this->once()) 
            ->method('savePatient'); // savePatient() must be called once

$this->controller->handleMessage(...);

$patient = ??; // How can I get the patient to make assertions with it ?

How can I do that, or is there any other way to make sure the patient is saved with a null phone number?

like image 872
aspyct Avatar asked Oct 19 '11 13:10

aspyct


2 Answers

You can make assertions on the argument using returnCallback(). Remember to call assert functions statically via PHPUnit_Framework_Assert because you cannot use self inside a closure.

$this->patientDao
        ->expects($this->once()) 
        ->method('savePatient')
        ->will($this->returnCallback(function($patient) {
            PHPUnit_Framework_Assert::assertNull($patient->getPhoneNumber());
        }));
like image 163
David Harkness Avatar answered Nov 05 '22 21:11

David Harkness


Here's the trick I used. I added this private method to my test class:

private function captureArg( &$arg ) {
    return $this->callback( function( $argToMock ) use ( &$arg ) {
        $arg = $argToMock;
        return true;
    } );
}

Then when setting up the mock:

$mock->expects( $this->once() )
    ->method( 'someMethod' )
    ->with( $this->captureArg( $arg ) );

After that, $arg contains the value of the argument passed to the mock.

like image 30
Andrew Avatar answered Nov 05 '22 22:11

Andrew