Удаление зависимости в конструкторе с помощью PHPunit - PullRequest
2 голосов
/ 15 сентября 2009

При попытке протестировать устаревшую кодовую базу я наткнулся на объект, который выполняет следующие действия:

class Foo
{
    public function __construct($someargs)
    {
        $this->bar = new Bar();
        // [lots more code]
    }
}

Бар в этом случае имеет конструктор, который делает некоторые плохие вещи, например подключение к базе данных. Я пытаюсь сосредоточиться на тестировании этого класса Foo, поэтому изменил его на что-то вроде этого:

class Foo
{
    public function __construct($someargs)
    {
        $this->bar = $this->getBarInstance();
        // [lots more code]
    }

    protected function getBarInstance()
    {
        return new Bar();
    }
}

И попытались проверить его с помощью следующего теста PHPUnit:

class FooTest extends PHPUnit_Framework_TestCase
{
    public function testInstance()
    {

        $bar = $this->getMock('Bar');
        $foo = $this->getMock('Foo', array('getBarInstance'));
        $foo->expects($this->any())
            ->method('getBarInstance')
            ->will($this->returnValue($bar));

    }

}

Однако это не работает - конструктор Foo () вызывается до того, как добавлен my -> Expected (), поэтому смоделированный метод getBarInstance () возвращает нуль.

Есть ли способ отсоединить эту зависимость без необходимости рефакторинга того, как класс использует конструкторы?

1 Ответ

4 голосов
/ 15 сентября 2009

Используйте аргумент $callOriginalConstructor getMock(). Установите значение false. Это пятый аргумент метода. Посмотрите здесь: http://www.phpunit.de/manual/current/en/api.html#api.testcase.tables.api

На самом деле, держись. Вы хотите передать макет макету? Если вы действительно этого хотите, то используйте третий аргумент getMock, который представляет аргументы конструктора. Там вы можете передать макет Bar на макет Foo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...