Установка $_POST для filter_input_array (INPUT_POST) в тесте phpunit - программирование

Установка $_POST для filter_input_array (INPUT_POST) в тесте phpunit

Имея некоторые проблемы с использованием PHPUnit для тестирования моих контроллеров.

В коде, к которому я работал до сих пор, была реализована $_POST или другие переменные запроса:

$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = array(
    'test' => true
);

Большинство тестов отлично работали таким образом, пока я не столкнулся с методами, использующими функцию filter_input_array:

$_SERVER['REQUEST_METHOD'] = 'POST';
$_REQUEST = $_POST = $GLOBALS['_POST'] = array(
    'test' => true
);

// ....

var_dump(filter_input_array(INPUT_POST));

NULL

Я не хочу удалять функции filter_input из не моего кода, но я не могу заставить их работать в тестах.

Versionings:
PHP 5.5.9-1ubuntu4.9 (cli) (построено: 17 апреля 2015 г. 11:44:57)
Apache/2.4.7 (Ubuntu)
PHPUnit 4.6.6 от Себастьяна Бергмана и авторов.

Любая помощь будет оценена.

EDIT 2015.05.11

Настройка $_SERVER с помощью CONTENT_LENGTH и CONTENT_TYPE не устраняет проблему. Моя версия PHP не позволяет мне писать на php://stdin так, как описано в PHP 5.6.0 chagelog (или как я его понимаю), но file_put_contents(STDIN,..) преуспевает, но не работает в любом случае.

Поскольку это тест phpunit, возможно, есть какая-то аннотация или запись phpunit.xml, которую я еще не знаю, что может решить эту проблему в настройке php-cgi POST способ.

4b9b3361

Ответ 1

Если ввод в filter_input_array может быть установлен только исходным запросом и не изменен во время выполнения, то единственный способ проверить его - это иметь базовый тестовый прокси для другого теста script, сделав HTTP-запрос с правильными данными POST и обработка ответа.

main_test.php:

<?php
$data = array(
    'testname' => 'yourtestname',
    'some_post_var' => 'some_value'
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/proxy_test.php");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

curl_close($ch);

if ($response == 'pass') {
  // test passed
}

proxy_test.php

<?php
$test_name $_POST['testname']; // what test to run?
$response = run_test($test_name); // run test that uses filter_input_array
if ($response) {
    echo "pass"; // used by main_test.php to check if test passed
} else {
   echo "fail";
}

Ответ 2

Похоже, что это ограничение PHP, filter_input_array() не позволяет изменять массив $_POST во время выполнения. См. эту ошибку для получения дополнительной информации. Обходным путем, вероятно, является использование одной из других функций фильтра и передать в массив $_POST самостоятельно.

Ответ 3

Если ни один из аргументов не установлен, эта функция возвращает NULL, not an array of NULL values.

//Нет запросов POST в запросе

$_POST = array();
$args = array('some_post_var' => FILTER_VALIDATE_INT);
$myinputs = filter_input_array(INPUT_POST, $args);
var_dump($myinputs);

Expected Output: array(1) { ["some_post_var"]=> NULL } 

Фактический выход: NULL

Во время фильтрации входных массивов будьте осторожны с флагами, которые вы устанавливаете помимо FILTER_REQUIRE_ARRAY. Например, установив такие флаги:

 <?php 
    $filter = array( 
    'myInputArr' => array('filter' => FILTER_SANITIZE_STRING, 
                          'flags' => array('FILTER_FLAG_STRIP_LOW', 'FILTER_REQUIRE_ARRAY')) 
    ); 

$form_inputs = filter_input_array(INPUT_POST, $filter); 
?> 

.. приведет к пустой $form_inputs ['myInputArr'] независимо от что $_POST ['myInputArr'] содержит.