PHPUnit: получить аргументы для вызова метода mock

В настоящее время я работаю над проектом, в котором хранятся конфиденциальные данные, и поэтому они могут удалять их по запросу.

Я хотел бы проверить, что моя сущность (пациент) сохраняется в базе данных с нулевым номером телефона. Сначала сделайте это: передайте аргумент PatientDao::savePatient(PatientModel $patient) и посмотрите на его атрибут phoneNumber.

Итак, вот интерфейс PatientDao:

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

И код в моем тестовом файле:

$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 ?

Как я могу это сделать или есть ли другой способ убедиться, что пациент сохранен с нулевым номером телефона?

Ответ 1

Вы можете сделать утверждения по аргументу, используя returnCallback(). Не забудьте вызвать функции assert статически через PHPUnit_Framework_Assert, потому что вы не можете использовать self внутри закрытия.

$this->patientDao
        ->expects($this->once()) 
        ->method('savePatient')
        ->will($this->returnCallback(function($patient) {
            PHPUnit_Framework_Assert::assertNull($patient->getPhoneNumber());
        }));

Ответ 2

Вот трюк, который я использовал. Я добавил этот закрытый метод в свой тестовый класс:

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

Затем при настройке mock:

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

После этого $arg содержит значение аргумента, переданного макету.

Ответ 3

Сделать метод Mock объектов первым аргументом:

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

Затем вы можете утверждать, что это NULL.