Я создал класс PHP, который конвертирует функции filter_input, чтобы облегчить жизнь нашего разработчика.
Чтобы проверить форму HTML с полями url
, name
и age
, код будет таким:
$post = Filter::POST(); if ($post->validate_string('name') && $post->validate_integer('age')) { $url = $post->sanitize_url('url'); }
Это будет то же самое, что:
if (filter_input(INPUT_POST,'name',FILTER_UNSAFE_RAW) && filter_input(INPUT_POST,'age',FILTER_VALIDATE_INTEGER)) { $url = filter_input(INPUT_POST,'url',FILTER_SANITIZE_URL); }
Ну, я думаю, код сделан, и теперь я хотел бы создать для него тест PHPUnit.
Проблема в том, что я понятия не имею, как подделывать данные GET / POST по методу PHPUnit, а не для этого случая.
Мне не нужно вставлять значения в $_POST
, мне нужны «настоящие» данные, потому что filter_input
работает с данными, полученными скриптом, а не с фактическим $_POST
.
Я попытался использовать следующий тест PHPT и метод PHPUnit для достижения этого, без каких-либо успехов:
--TEST-- Generates POST and GET data to be used in FilterTest.php --POST-- name=Igor&age=20 --GET-- name=Igor&age=19 --FILE-- <?php echo $_POST['nome'].' = '.$_POST['idade']; ?> --EXPECT-- Igor = 20
public function testPhpt() { $phpt = new PHPUnit_Extensions_PhptTestCase('FilterTest_data.phpt', array('cgi' => 'php-cgi')); $result = $phpt->run(); $this->assertTrue($result->wasSuccessful()); }
Исходный код : http://pastebin.com/fpw2fpxM
Код, используемый для первоначального тестирования : http://pastebin.com/vzxsBQWm
(извините за португальский язык, я знаю, что было бы лучше писать на английском языке, но это то, как все работает здесь, где я работаю. Если вы действительно думаете, что это действительно необходимо, я могу перевести код).
Любая идея о том, что я могу сделать, чтобы протестировать этот класс?
Вы не можете подделывать необработанные данные POST. Но проблема заключается в вашем коде: он не тестируется на единицу. Вместо:
if (filter_input(INPUT_POST,'name',FILTER_UNSAFE_RAW) && filter_input(INPUT_POST,'age', FILTER_VALIDATE_INTEGER)) { $url = filter_input(INPUT_POST,'url',FILTER_SANITIZE_URL); }
Если у тебя есть:
if (filter_var($data['name'], FILTER_UNSAFE_RAW) && filter_var($data['age'], FILTER_VALIDATE_INT)) { $url = filter_var($data['url'], FILTER_SANITIZE_URL); } // where $data is a copy of $_POST in that case
Предоставило бы ваш блок кода тестируемым и равным тому же, что и ваш предыдущий код.
PS: FILTER_VALIDATE_INTEGER недействителен. Правильной константой для этого является FILTER_VALIDATE_INT
В вашем коде есть 2 проблемы. Во-первых, вы получаете доступ к глобальным переменным, которые трудно проверить. Во-вторых, вы сильно привязываете класс к конкретным данным (post, get и т. Д.).
То, что вы должны сделать, это заставить класс удовлетворять такому интерфейсу:
$filter = new Filter($_POST); $filter->validate_string('name');
Выгоды должны быть очевидны. Вам не нужно использовать $_POST
или $_GET
или любой другой предопределенный тип в качестве входных данных. Вы можете не только проверять входные данные из любого источника (поскольку вы просто передаете его в конструктор), что более важно, вы можете вводить любые данные там, где вам нравится тестирование.
Woops, я пропустил часть об использовании filter_input
. Решение состоит в filter_var
чтобы вместо этого использовать filter_var
. Он позволяет запускать фильтры по любой переменной.