Weiß jemand, ob es eine assert
oder etwas Ähnliches, das prüfen kann, ob im getesteten Code eine Ausnahme ausgelöst wurde?
Antworten
Zu viele Anzeigen?Der folgende Code testet die Ausnahmemeldung und den Ausnahmecode.
Das ist wichtig: Er schlägt fehl, wenn die erwartete Ausnahme nicht auch ausgelöst wird.
try{
$test->methodWhichWillThrowException();//if this method not throw exception it must be fail too.
$this->fail("Expected exception 1162011 not thrown");
}catch(MySpecificException $e){ //Not catching a generic Exception or the fail function is also catched
$this->assertEquals(1162011, $e->getCode());
$this->assertEquals("Exception Message", $e->getMessage());
}
Sie können verwenden assertException-Erweiterung um mehr als eine Ausnahme während einer Testausführung geltend zu machen.
Methode in Ihren TestCase einfügen und verwenden:
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}
Ich habe auch eine Eigenschaft für Liebhaber des schönen Codes..
Das PHPUnit expectException
Methode ist sehr ungünstig, da sie nur eine Ausnahme pro Testmethode zulässt.
Ich habe diese Hilfsfunktion erstellt, um zu behaupten, dass eine Funktion eine Ausnahme auslöst:
/**
* Asserts that the given callback throws the given exception.
*
* @param string $expectClass The name of the expected exception class
* @param callable $callback A callback which should throw the exception
*/
protected function assertException(string $expectClass, callable $callback)
{
try {
$callback();
} catch (\Throwable $exception) {
$this->assertInstanceOf($expectClass, $exception, 'An invalid exception was thrown');
return;
}
$this->fail('No exception was thrown');
}
Fügen Sie sie zu Ihrer Testklasse hinzu und rufen Sie sie so auf:
public function testSomething() {
$this->assertException(\PDOException::class, function() {
new \PDO('bad:param');
});
$this->assertException(\PDOException::class, function() {
new \PDO('foo:bar');
});
}
Umfassende Lösung
PHPUnit's aktuelle " beste Praktiken " für Ausnahmetests scheinen glanzlos ( docs ).
Da ich mehr gesucht als die aktuelle expectException
Implementierung habe ich einen Trait für meine Testfälle erstellt. Es ist nur ~50 Zeilen Code .
- Unterstützt mehrere Ausnahmen pro Test
- Unterstützt Assertions, die aufgerufen werden, nachdem die Ausnahme ausgelöst wurde
- Robuste und klare Anwendungsbeispiele
- Standard
assert
Syntax - Unterstützt Assertions für mehr als nur Nachricht, Code und Klasse
- Unterstützt die inverse Behauptung,
assertNotThrows
- Unterstützt PHP 7
Throwable
Fehler
Bibliothek
Ich habe die AssertThrows
Eigenschaft auf Github und Verpacker damit es mit Composer installiert werden kann.
Einfaches Beispiel
Nur um den Sinn der Syntax zu verdeutlichen:
<?php
// Using simple callback
$this->assertThrows(MyException::class, [$obj, 'doSomethingBad']);
// Using anonymous function
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
Ist das nicht toll?
Beispiel für die vollständige Verwendung
Ein ausführlicheres Beispiel für die Verwendung finden Sie weiter unten:
<?php
declare(strict_types=1);
use Jchook\AssertThrows\AssertThrows;
use PHPUnit\Framework\TestCase;
// 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();
});
}
}
?>