Я иногда чувствую, что люди чрезмерно используют Design For Testability, заканчивая кодом, где 80% сложности, похоже, просто облегчает тестирование. Я чувствую, что часто лучше переключиться на функциональное тестирование на вещи, которые становятся беспорядочными для модульного теста.
Но для супер-глобалов PHP я сдаюсь. Поэтому я стараюсь избегать использования $ _POST или $ _GET в любом коде фреймворка и вместо этого использовать параметр или, если это делает код слишком уродливым, то член класса или статический член.
Таким образом, Вы получаете() функция может быть переписано следующим образом:
public static function get($name,$default,$GET=null)
{
if($GET===null)$GET=$_GET; //For non-test code
if(!array_key_exists($name,$GET))return $default;
return $GET[$name];
}
Тогда ваш тест становится:
public function testGET()
{
$GET=array('test' => 'test value');
$get_value = Input::get('test', '[default value]', $GET);
$this->assertEquals('test value', $get_value);
}
Это быстро становится неудобно, когда вызов на вход :: получить() глубоко погружен в иерархию вызовов; то статический член класса лучше. Чтобы использовать член класса, $ GET можно передать в функции init()
. Но если иметь в init()
функцию неуместно, это может быть сделано, как это:
public static $GET=null;
public static function get($name,$default)
{
if(self::$GET===null)self::$GET=$_GET; //Init on first call
if(!array_key_exists($name,self::$GET))return $default;
return $GET[$name];
}
И тогда испытание становится:
public function testGET()
{
Input::$GET=array('test' => 'test value');
$get_value = Input::get('test', '[default value]');
$this->assertEquals('test value', $get_value);
}
Помимо: другой (не тестирование) причина мне нравится этот подход что позволяет клиенту-код, чтобы выбрать использовать $_GET
, $_POST
, $_REQUEST
и т.д. Так что я бы назвал статическую переменную self::$INPUT
, и имеют init()
функцию, где пользователь должен пройти в $_POST
или $_GET
или то, что они хотят.
Вторая половина вашего вопроса задает вопрос о тестировании данных PUT и DELETE. Однако вы не сказали, как он обрабатывается в реальном коде. Есть ли у вас какой-то код, аналогичный показанному в этом ответе: https://stackoverflow.com/a/5374881/841830
Если это так, один подход издеваться функции getContent()
, как показано там, чтобы вернуть жесткий кодированный текст, вместо того, чтобы получать его от php://input
. Другой подход состоит в том, чтобы иметь другую функцию (в вашем реальном классе), главным образом для тестирования, которая входит и устанавливает $this->content
перед первым вызовом, который будет использовать эту переменную. ($this->content
в этом ответе в основном похож на переменную self::$INPUT
, о которой я упоминал ранее.)
Вы бы высмеивали Input :: get(), чтобы возвращать текст, который вы ожидаете, а затем проверите свой код соответственно. Похоже, вы на правильном пути, вам просто нужно сделать Mock вместо форматирования глобальных переменных. –