I want to test that my function refuses all non-positive integers. It throws an InvalidArgumentException. I wrote a test like this:
/**
* @test
* @expectedException InvalidArgumentException
*/
public function testXThrowsException()
{
$this->parser->x(1.5);
$this->parser->x('2');
$this->parser->x(1000E-1);
$this->parser->x(+100);
}
My test always passes because the first one throws an exception. The others don't get tested properly. I can add $this->parser->x(1);
to my code and it would still pass.
What should I do to assert that all these function calls raise the InvalidArgumentException?
/**
* @test
* @expectedException InvalidArgumentException
*
* @dataProvider foo
*/
public function testXThrowsException($value)
{
$this->parser->x($value);
}
/**
* Test data
* Returns array of arrays, each inner array is used in
* a call_user_func_array (or similar) construction
*/
public function foo()
{
return array(
array(1.5),
array('2'),
array(1000E-1),
array(+100)
);
}
A solution would be to use it like this:
/**
* @test
*/
public function testXThrowsException()
{
try {
$this->parser->x(1.5);
$this->fail('message');
} catch (InvalidArgumentException $e) {}
try {
$this->parser->x('2');
$this->fail('message');
} catch (InvalidArgumentException $e) {}
try {
$this->parser->x(1000E-1);
$this->fail('message');
} catch (InvalidArgumentException $e) {}
try {
$this->parser->x(+100);
$this->fail('message');
} catch (InvalidArgumentException $e) {}
}
Now you can test every line on its own. Whenever method x()
does not raise an exception, the test fails using fail()
.
If you have alot of negative values you could also put them in an array, and loop over the array with the following code (without testing):
foreach($wrongValueArray as $failtyValue) {
try { $this->parser->x($failtyValue);
this->fail($failtyValue . ' was correct while it should not');
} catch (InvalidArgumentException $e) {}
}
It's a bit shorter