ZendFramework Использование Mock

Professor

Новичок
Добрый день.
Целый день мучаюсь, и непонятно, то ли я не правильно делаю, то ли что то не так настроено.
Использую ZendFramwork 1.8 и PHPunit 4.1

Правильно ли я понимаю что пример приведенный ниже будет работать так:

PHP:
class MyClass(){
    function a(){
        $val = (new TimerClass())->getTime();
        echo val;
  }
}
class TimerClass(){
    function getTime(){
    return 12;
    }
}
PHP:
class MyClassTest(){
    function testA(){


    $mock  = $this->getMock('TimerClass');
    $this->assertInstanceOf('TimerClass', $mock);
    $mock->method('getTime') ->will($this->returnValue('77'));

       $body = $this->getResponse()->getBody();
        echo $body;
  }
}
}
Немного упростил, но все же. Правильно ли я понимаю что при выполнении теста, должно вывестись "77" а не "12"


У меня так не получается.
Вот если я в тесте делаю так
$mock->getZoneByKladr()



PHP:
class MyClassTest(){
    function testA(){
    $mock  = $this->getMock('TimerClass');
    $this->assertInstanceOf('TimerClass', $mock);
    $mock->method('getTime') ->will($this->returnValue('77'));
    $body = $this->getResponse()->getBody();

    echo $mock->getTime();
    echo $body;
  }
}
}
То выводится 77 и 12
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
PHP:
(new TimerClass())->getTime();
Это то же самое, что и
PHP:
TimerClass::getInstance()->getTime();
А синглтоны нормально не мокаются.

Тебе нужно протащить эту зависимость через конструктор/сеттер.
Технически, mock реализован через создание временного класса-наследника, который и переопределяет методы. Но с исходным классом ничего не происходит, поэтому ты получаешь то, что получаешь.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Вурдалак, я в последнее время начинаю осознавать полезность ларавал-фасадов. :) Нормально управлять зависимостями осилит не каждый профессор, а с фасадами хоть тестировать можно.
 

Professor

Новичок
Вурдалак, спасибо, теперь понял.
Тогда такой вопрос:
У меня есть действие(там только прием параметров, и вызов необходимых функций)

Мне нужно протестировать это действие, при этом не хочется конектиться к базе.

Хочется что бы во время теста подключались не реальные модели, а тестовые модели, которые будут выдавать заранее заложенные в них данные.

Вопрос: В какую сторону копать? Как это называется? Или я все не правильно себе представляю?
 

AmdY

Пью пиво
Команда форума
Professor, В случае контроллера я бы не парился юнит тестом, написал бы функциональный, зенд их поддерживает из коробки, насколько помню.
Моки это фактически класическое наследование при котором нужные методы перекрываются.
PHP:
$mock  = $this->getMock('TimerClass');
$mock->method('getTime') ->will($this->returnValue('77'));
// преобразовывается
class TimerClass_uniq_id extends TimerClass {
    public function getTime() {
        return 777;
    }
}
Чтобы использовать мок, его нужно куда-нибудь передать. Самый простой способ - добавить геттер зависимости, который потом будет мочиться. Ну и нельзя пользоваться echo, die и т.д.
 

Professor

Новичок
fixxxer, спасибо. Со вторым вариантом понятно, а про первый, можно немного подробней?
 
Сверху