Ложный закрытый метод в тестовой функции от PHPUnit - PullRequest
0 голосов
/ 20 августа 2011

Написание модульных тестов для уже написанного кода иногда забавно.

Я пишу контрольный пример для следующего кода (пример):

<?php

class mockPrivate {

    public static function one($a){
        $var = static::_two($a);
        return $var;
    }

    private static function _two($a){
        return $a+1;
    }
}
?>

Тестовый класс выглядит так:

<?php

require_once 'mockPvt.php';

class mockPrivate_test extends PHPUnit_Framework_TestCase {
    public $classMock;
    protected function setUp(){ 
         $this->classMock = $this->getMock('mockPrivate', array('_two'));
    }

    public function test_one(){
        $a = 1;
        $retVal = 2;
        $classmock = $this->classMock;
        $classmock::staticExpects($this->once())
            ->method('_two')
            ->with($a)
            ->will($this->returnValue($retVal));
        $value = $classmock::one($a);
        $this->assertEquals($value, $retVal);                
    }    
}

?>

После запуска по $ phpunit mockPrivate_test.php я получил эту ошибку:

PHP Fatal error:  Call to private method Mock_mockPrivate_531a1619::_two() from context 'mockPrivate' in /data/www/dev-sumit/tests/example
s/mockPvt.php on line 6

Но если я поменяю

private    static function _two() 
to 
public     static function _two() or 
protected  static function _two() 

это работает совершенно нормально. Поскольку это устаревший код, я не могу изменить private to public/protected. Так есть ли способ проверить функцию один или это ограничение phpunit?

Ответы [ 3 ]

2 голосов
/ 03 мая 2012

Другой вариант - создать класс, который расширяет mockPrivate, предоставляя доступ к объекту, который вы хотите протестировать.Ваши инженеры должны долго и усердно думать о том, почему что-то является частным (потому что это означает, что класс не является легко расширяемым).Также помните, что вы можете смоделировать тестовый класс, если вам нужно переопределить то, что он возвращает.

class Test_MockPrivate extends MockPrivate
{
    /**
     * Allow public access to normally protected function
     */
    public static function _two($a){
        return parent::_two($a);
    }
}

// Code to force the return value of a now public function
$mock = $this->getMock('Test_MockPrivate', array('_two'));
$mock->expects($this->any())
    ->method('_two')
    ->will($this->returnValue('Some Overridden Value');
1 голос
/ 20 августа 2011

Вы можете использовать отражение для изменения видимости методов. Вы можете найти больше информации в PHP объект, как ссылаться?

0 голосов
/ 23 сентября 2013

Использовать макет и отражение ... (разместил это решение, так как это лучший результат Google)

$oMock = $this->getMock("Your_class", array('methodToOverride'));
$oMock->expects( $this->any() )
    ->method('methodToOverride')
    ->will( $this->returnValue( true ) );

$oReflection = new ReflectionClass("Your_Class");

$oMethod = $oReflection->getMethod('privateMethodToInvoke');
$oMethod->setAccessible( true );
$oMethod->invoke( $oMock );
...