Тестирование объектов с зависимостями в PHPUnit

Во-первых, ср. эта страница , чтобы объяснить, почему не использовать

for i in `cat list1.txt`

... когда-либо.

Во-вторых, это , почему бы не использовать

cat list2.txt | awk ...

Извините за арфу. Теперь ... попробуйте

while read -r val || [[ -n "$val" ]] 
do awk "/$val/ { flag=1; next } /Flag2/ { flag=0 } flag" list2.txt
done < list1.txt

awk в двойных кавычках ... не идеально. Или, как предлагает Чарльз, используйте -v (всегда слушайте Charles & amp ... Ed ...)

while read -r val || [[ -n "$val" ]] 
do awk -v i="$val" '
     [113] ~ i  { flag=1; next } 
     /Flag2/ { flag=0; }
     flag
   ' list2.txt
done < list1.txt

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

Обратите внимание, что || [[ -n "$val" ]] необходимо только в том случае, если есть вероятность, что в последней записи не будет перевода строки.

9
задан fmsf 13 February 2009 в 12:04
поделиться

4 ответа

Поскольку Вы, кажется уже, знаете, Зависимости от Реального класса делает тестирование трудно (или напрямую невозможный). Необходимо отделить ту зависимость. Простое изменение, которое не повреждает существующий API, состоит в том, чтобы принять значение по умолчанию к текущему поведению, но обеспечить рычаг для переопределения его. Существует много способов, которыми это могло быть реализовано.

Некоторые языки имеют инструменты, которые могут ввести ложные классы в код, но я не знаю ни о чем как это для PHP. В большинстве случаев Вы, вероятно, были бы более обеспеченным рефакторингом Вашего кода так или иначе.

4
ответ дан 4 December 2019 в 21:12
поделиться

После troelskn советуют, вот основной пример того, что необходимо сделать.

<?php

class MyObj
{
    /**
     * @var LoggerInterface
     */
    protected $_logger;

    public function doSomethingWhichIsLogged()
    {
        // ...
        $this->getLogger()->info('some message');
        // ...
    }

    public function setLogger(LoggerInterface $logger)
    {
        $this->_logger = $logger;
    }

    public function getLogger()
    {
        return $this->_logger;
    }
}


class MyObjText extends PHPUnit_Framework_TestCase
{
    /**
     * @var MyObj
     */
    protected $_myObj;

    public function setUp()
    {
        $this->_myObj = new MyObj;
    }

    public function testDoSomethingWhichIsLogged()
    {
        $mockedMethods = array('info');
        $mock = $this->getMock('LoggerInterface', $mockedMethods);
        $mock->expects($this->any())
             ->method('info')
             ->will($this->returnValue(null));

        $this->_myObj->setLogger($mock);

        // do your testing
    }
}

Больше информации о фиктивных объектах может быть найдено в руководстве.

6
ответ дан 4 December 2019 в 21:12
поделиться

Похож я неправильно понял вопрос, позвольте мне попробовать еще раз:

Необходимо использовать шаблон "одиночка" или фабрику для регистратора, если уже не слишком поздно:

class LoggerStub extends Logger {
    public function info() {}
}
Logger::setInstance(new LoggerStub());
...
$logger = Logger::getInstance();

Если Вы не можете изменить код, Вы могли бы использовать всеобъемлющий класс, который перегружается __ вызов ()

class GenericStub {
    public function __call($functionName, $arguments) {}
}
0
ответ дан 4 December 2019 в 21:12
поделиться

На самом деле существует достаточно новое расширение для перегрузки классов PHP, выпущенное теми же ребятами, которые создают PHPUnit. Оно позволяет вам переопределять оператор new в случаях, когда вы не можете рефакторить код, но, к сожалению, его не так просто установить на Windows.

URL: http://github.com/johannes/php-test-helpers/blob/master/

0
ответ дан 4 December 2019 в 21:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: