Exception testing assertions for PHPUnit.
You can install with composer if you're into that. Just make sure that your vendor/autoload.php file is included in your PHPUnit bootstrap file.
composer require --dev jchook/phpunit-assert-throwsAlternatively, simply download the one file and include it in your project.
PHPUnit's current "best practices" for exception testing seem.. lackluster (docs).
Since I wanted more than the current expectException implementation, I made a trait to use on my test cases.
- Supports multiple exceptions per test
- Supports assertions called after the exception is thrown
- Clear usage examples
- Standard
assertsyntax - Supports assertions for more than just
message,code, andclass - Supports inverse assertion,
assertNotThrows
Just to illustrate the spirit behind the syntax:
// Within your test case...
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});Pretty neat?
Here is an actual TestCase class that shows a more comprehensive usage example:
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use Jchook\AssertThrows\AssertThrows;
// These are just for illustration
use MyNamespace\MyException;
use MyNamespace\MyObject;
final class MyTest extends TestCase
{
use AssertThrows; // <--- adds the assertThrows method
public function testMyObject()
{
$obj = new MyObject();
// Test a basic exception is thrown
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
// Test custom aspects of a custom extension class
$this->assertThrows(MyException::class,
function() use ($obj) {
$obj->doSomethingBad();
},
function($exception) {
$this->assertEquals('Expected value', $exception->getCustomThing());
$this->assertEquals(123, $exception->getCode());
}
);
// Test that a specific exception is *NOT* thrown
$this->assertNotThrows(MyException::class, function() use ($obj) {
$obj->doSomethingGood();
});
}
}
?>I realize that assertNotThrows() is grammatically... odd, but it's in keeping with the PHPUnit naming conventions, such as assertNotContains(). Additionally, the PHPUnit team's philosophy is that this inverse assertion is not even needed.
MIT