How to make a PHPUnit test that depends on ~real~ POST/GET data?

You can't fake raw POST data. But the problem lies in your code: it's not unit-testable. Instead of:

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 you had:

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

Would render your code unit testable and amount to the same thing as your previous code did.

P.S.: FILTER_VALIDATE_INTEGER is not valid. The proper constant for this is FILTER_VALIDATE_INT


There are 2 problems with your code. One is that you're accessing global variables, which are hard to test. The second is you're tightly binding the class to specific data (post, get, etc).

What you should do is make the class satisfy this kind of interface:

$filter = new Filter($_POST);
$filter->validate_string('name');

The benefits should be obvious. You don't have to use $_POST or $_GET or any other predefined type as inputs. Not only can you now validate input from any source (since you just pass it into the constructor), more importantly, you can inject any data into there you like for the purpose of testing.

Woops, I missed the part about using filter_input. The solution is to use filter_var instead. It allows you to run the filters on any variable.