Продолжу прошлый пост о юнит-тестировании внутренних методов  — я чуть усовершенствовал конструкцию

Итак, вначале я пишу тест-кейс наследую PHPUnit_Framework_TestCase. Потом я include’жу тестируемый класс. Инициализирую его в $this->object внутри тест кейса. Теперь, если в тестируемом объекте есть какой-то метод нафаршированный внутренними вызовами, которые мне мешают (например под-запросы в БД и тп.), то я могу их обрубить перезаписью методов на лету с runkit.

Скажем метод

function makePain(){
    $foot = $this->getFootFromDB();
    $shootingResults = $this->shootAt($foot);
    return ($shootingResults["screams"]>5)
}

У меня тестируется так

/**
 * @test
 */
function makePain(){
    $this->mockMethodRewrite('getFootFromDB', function () {
         return array('james bonds foot', 45);
    });
    $this->assertTrue($this->object->makePain());
}

В данном случае настоящий код getFootFromDB перезаписывается на callable который я предоставляю. Внутри анонимная функция конвертируется в строку и передаётся в runkit. Конвертацию смотрите на stackoverflow.
А сделан он так..

/**
 * Rewrites method code to support mocking of private/protected and just internal method calls
 *
 * @param string $method .
 * @param string $method_code .
 * @param bool $class .
 */
public function mockMethodRewrite($method, $method_code, $class = false) {
    $codeToPassToRunkit = CallableStringifier::stringify($method_code);
    runkit_method_redefine(
        $class ? $class : get_class($this->object),
        $method, //ReflectionFunction::export($method_code, true),
        '',
        $codeToPassToRunkit,
        RUNKIT_ACC_PUBLIC
);
}

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *