How to Use PHPunit to Test a Function If That Function Is Supposed to Kill PHP

How do you use PHPUnit to test a function if that function is supposed to kill PHP?

As every tests are run by the same PHPUnit process, if you use exit/die in your PHP code, you will kill everything -- as you noticed ^^

So, you have to find another solution, yes -- like returning instead of dying ; or throwing an exception (you can test if some tested code has thrown an expected exception).

Maybe PHPUnit 3.4 and it's --process-isolation switch (see Optionally execute each test using a separate PHP process) might help (by not having everything dying), but you still wouldn't be able to get the result of the test, if PHPUnit doesn't get the control back.

I've had this problem a couple of times ; solved it by returning instead of dying -- even returning several times, if needed, to go back "high enough" in the call stack ^^

In the end, I suppose I don't have any "die" anymore in my application... It's probably better, when thinking about MVC, btw.

PHP Unit testing fails to pass all test

While testing for the testIllegalParameters() which expects an exception in return, you don't have to use try-catch block. Just throw an exception in an if condition simply.

Secondly throw a correct type of exception that is defined in the test case InvalidArgumentException

class Offset
{
public function __construct(int $offset = 13)
{
if ($offset < 0) {
throw new InvalidArgumentException('Offset should be greater than equal to zero');
} else {
$this->offset = $offset;
}
}
}

testing exceptions with phpunit

I generally use the @expectedException annotations for just such cases. See all exception-related annotations here:

/**
* @expectedException \Exception
* @expectedExceptionCode 2
*/
function testSetAdsData_dataIsNull()
{
$dataArr = null;
$fixture = new AdGroup();

$fixture->setAdsData($dataArr);
}

Checking that $fixture->ads is really null doesn't really add up here, you can add these asserts prior to the call that actually triggers an exception:

$this->assertNull($fixture->ads);
$fixture->setAdsData($dataArr);//throws exception

You're unit testing. This test serves a clear purpose: it makes sure an exception is thrown in a given situation. If it does, then that's where the test ends.

Still, if you want to keep those assertEmpty calls, you could do this:

try {
$fixture->setAdsData($dataArr);
$e = null;
} cathc (Exception $e) {}
$this->assertEmpty($fixture->ads);
$this->assertEmpty($fixture->adIds);
if (!$e instanceof \Exception) {
//if the exception is not thát important:
$this->markTestIncomplete('No Exception thrown');
//do other stuff here... possibly
$this->fail('The exception was not thrown');
}
throw $e;//throw exception a bit later

An alternative approach would be to call $this->setExpectedException manually as explained here. Since we don't seem to know/care what the exception message will look like, I'm going to use the setExpectedExceptionRegExp method:

$fixture = new AdGroup();
$this->setExpectedExceptionRegExp(
//exception class, message regex, exception code
'Exception', '/.*/'. 2
);
$fixture->setAdsData(null);//passing null seems to be what you're doing anyway

How do I test for multiple exceptions with PHPUnit?

As exceptions are such big events in the program flow, testing multiple ones in a single test is problematic.

The easiest thing is is to simply split it into two tests - the first requires an exception to be able to pass, the second simply runs, and would fail it it did throw one. You could add some other tests in the second if you wanted (confirming a return value maybe), but I'd be inclined to make sure it still did just the one essential thing, according to the naming of it.

/**
* @expectedException Exception
*/
public function testBadFooThrowsException()
{
// optional, can also do it from the '@expectedException x'
//$this->setExpectedException('Exception');
foo(-1); //throws exception -- good.
}

public function testFooDoesNotThrowException()
{
foo(1); //does not throw exception
}


Related Topics



Leave a reply



Submit