PHPUnit asserisce che è stata lanciata un'exception?

Qualcuno sa se c'è un assert o qualcosa di simile che può verificare se è stata lanciata un'exception nel codice in prova?

 <?php require_once 'PHPUnit/Framework.php'; class ExceptionTest extends PHPUnit_Framework_TestCase { public function testException() { $this->expectException(InvalidArgumentException::class); // or for PHPUnit < 5.2 // $this->setExpectedException(InvalidArgumentException::class); //...and then add your test code that generates the exception exampleMethod($anInvalidArgument); } } 

expectException () Documentazione PHPUnit

L'articolo dell'autore PHPUnit fornisce una spiegazione dettagliata sulla verifica delle migliori pratiche relative alle eccezioni.

Puoi anche utilizzare un'annotazione di docblock :

 class ExceptionTest extends PHPUnit_Framework_TestCase { /** * @expectedException InvalidArgumentException */ public function testException() { ... } } 

Per PHP 5.5+ (in particolare con il codice dei nomi), ora preferisco usare ::class

Se stai utilizzando PHP 5.5 o versioni successive, puoi utilizzare la risoluzione ::class per get il nome della class con expectException / setExpectedException . Questo offre diversi vantaggi:

  • Il nome sarà pienamente qualificato con il suo spazio dei nomi (se presente).
  • Si risolve in una string modo che funzioni con qualsiasi versione di PHPUnit.
  • Ottieni il completamento del codice nel tuo IDE.
  • Il compilatore PHP emetterà un errore se si configura il nome della class.

Esempio:

 namespace \My\Cool\Package; class AuthTest extends \PHPUnit_Framework_TestCase { public function testLoginFailsForWrongPassword() { $this->expectException(WrongPasswordException::class); Auth::login('Bob', 'wrong'); } } 

Compilazioni PHP

 WrongPasswordException::class 

in

 "\My\Cool\Package\WrongPasswordException" 

senza PHPUnit è il più saggio.

Nota : PHPUnit 5.2 ha introdotto expectException come sostituto di setExpectedException .

Il codice seguente testerà il messaggio di exception e il codice di exception.

Importnte: fallirà se l'exception prevista non viene generata.

 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()); } 

È ansible utilizzare l'estensione assertException per far valere più di un'exception durante l'esecuzione di un test.

Inserisci il metodo nel tuo TestCase e usa:

 public function testSomething() { $test = function() { // some code that has to throw an exception }; $this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' ); } 

Ho anche fatto un tratto per gli amanti del bel codice ..

 public function testException() { try { $this->methodThatThrowsException(); $this->fail("Expected Exception has not been raised."); } catch (Exception $ex) { $this->assertEquals($ex->getMessage(), "Exception message"); } } 

Un modo alternativo può essere il seguente:

 $this->expectException(\Exception::class); $this->expectExceptionMessage('Expected Exception Message'); 

Assicurati che la tua class di test estenda \ PHPUnit_Framework_TestCase

Ecco tutte le eccezioni che puoi fare. Nota che tutti sono opzionali .

 class ExceptionTest extends PHPUnit_Framework_TestCase { public function testException() { // make your exception assertions $this->expectException(InvalidArgumentException::class); // if you use namespaces: // $this->expectException('\Namespace\MyExceptio‌​n'); $this->expectExceptionMessage('message'); $this->expectExceptionMessageRegExp('/essage$/'); $this->expectExceptionCode(123); // code that throws an exception throw new InvalidArgumentException('message', 123); } public function testAnotherException() { // repeat as needed $this->expectException(Exception::class); throw new Exception('Oh no!'); } } 

La documentazione può essere trovata qui .

 /** * @expectedException Exception * @expectedExceptionMessage Amount has to be bigger then 0! */ public function testDepositNegative() { $this->account->deposit(-7); } 

Fai molta attenzione a "/**" , nota il doppio "*". Scrivendo solo "**" (asterisco) fallirà il tuo codice. Assicurati anche di utilizzare l'ultima versione di phpUnit. In alcune versioni precedenti di phpunit @ unexpectedException Exception non è supportto. Avevo 4.0 e non ha funzionato per me, ho dovuto aggiornare a 5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composer per aggiornare con il compositore.

Il metodo PHPUnit expectException è molto scomodo perché consente di testare solo un'exception per un metodo di test.

Ho fatto questa function di supporto per affermare che alcune funzioni lanciano un'exception:

 /** * 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); return; } $this->fail('No exception was thrown'); } 

Aggiungilo alla tua class di test e chiama in questo modo:

 public function testSomething() { $this->assertException(\PDOException::class, function() { new \PDO('bad:param'); }); $this->assertException(\PDOException::class, function() { new \PDO('foo:bar'); }); }