views:

660

answers:

2

What's the best way to test $_GET and $_POST inputs in PHPUnit?

I have a class that sanitises input and want to check that it works correctly when processing bogus data. Is there an easy way to set up the form variables in PHPUnit or should I just pass off the validation to a secondary class/functions that are fed the form variables so test them indirectly?

A: 

Excuse me, but it seems to me you're trying to defeat the purposes of Unit Tests by doing so. Unit Tests ought to be repeatable and automatic. Expecting some variable input will make your tests fail or work depending on your input, without any changes to your code.

What you're trying to do here are Integration tests. They have also their use, of course, but that's out of scope of unit Testing and phpunit .

Johan Buret
+6  A: 

Take a look at the idea of Dependency injection. In a nutshell you should feed your code what it needs as opposed to it getting the data it needs... Here's an example:

example without Dependency Injection

function sanitize1() {
  foreach($_POST as $k => $v) {
    // code to sanitize $v
  }
}

sanitize1();

example with Dependency Injection

function sanitize2(array &$formData) {
  foreach($formData as $k => $v) {
    // code to sanitize $v
  }
}

sanitize2($_POST);

See the difference? In your PHPUnit test you can pass sanitize2() an associative array of your choice; you've injected the dependency. Whereas sanitize1() is coupled with $_POST. $_POST and $_GET are assoc arrays anyways so in your production code you can pass $_GET or $_POST to your function but in your unit tests you'd hard code some expected data.

Unit test example:

function testSanitize() {
  $fakeFormData = array ('bio' => 'hi i\'m arin', 'location' => 'San Francisco');
  sanitize($fakeFormData);
  // assert something
}
arin sarkissian
Thanks for that - I figured that was probably the best solution. Very good answer too!
Colonel Sponsz