JUnit Test d'exception attendu : @Test (attendu)

โšก Rรฉsumรฉ intelligent

JUnit Les tests d'exception confirment qu'une mรฉthode lรจve l'erreur qu'elle est censรฉe lever, en utilisant le paramรจtre optionnel expected de l'annotation @Test. JUnit 4 et la mรฉthode assertThrows dans JUnit 5.

  • (I.e. Objectif : Dรฉmontrez qu'une entrรฉe invalide produit l'exception documentรฉe au lieu d'une rรฉponse incorrecte silencieuse.
  • โ˜‘๏ธ syntaxe: @Test(expected = ArithmeticException.class) rรฉussit uniquement lorsque ce type d'exception exact est levรฉ.
  • โœ… Exemple : JUnitLe message est divisรฉ par zรฉro, et AirthematicTest s'attend ร  ce que l'exception ArithmeticException rรฉsultante soit levรฉe.
  • ๐Ÿงช Alternative: Un bloc try suivi de fail() vous permet d'inspecter l'exception interceptรฉe avant de la vรฉrifier.
  • ๏ธ JUnit 5: La fonction assertThrows renvoie l'exception interceptรฉe, ce qui permet รฉgalement d'affirmer le message et la cause.
  • ๐Ÿ“Œ Piรจge: Le paramรจtre attendu est transmis quel que soit le lieu oรน l'exception se produit, ce qui peut masquer une dรฉfaillance dans le code de configuration.

JUnit test d'exception attendu utilisant le paramรจtre @Test(expected)

JUnit offre la possibilitรฉ de trace l'exception et aussi pour vรฉrifier si le code lรจve l'exception attendue ou non.

JUnit La section 4 offre une mรฉthode simple et lisible pour tester les exceptions. Vous pouvez utiliser :

  • Le paramรจtre optionnel (attendu) de Annotation @Test et
  • ร€ tracร  partir de ces informations, la fonction ยซ fail() ยป peut รชtre utilisรฉe.

Si vers les tests En cas d'exception, vous devez vous assurer que la classe d'exception que vous fournissez dans ce paramรจtre optionnel de Annotation @Test est la mรชme que celle que la mรฉthode lรจve rรฉellement. Cela s'explique par le fait que vous attendez une exception de la mรฉthode que vous utilisez. tests unitaires; sinon notre JUnit le test รฉchouerait.

Exemple : @Test(expected = IllegalArgumentException.class)

En utilisant le paramรจtre ยซ expected ยป, vous pouvez spรฉcifier le nom de l'exception que notre test peut lever. Dans l'exemple ci-dessus, vous utilisez ยซException d'argument illรฉgal", qui sera levรฉe par le test si un dรฉveloppeur utilise un argument non autorisรฉ.

Exemple utilisant @Test(expected)

Comprenons les tests d'exceptions en crรฉant un Java classe avec une mรฉthode qui lรจve une exception exceptionVous gรฉrerez et testerez cela dans une classe de test. Considรฉrez JUnitLe fichier Message.java contient une mรฉthode effectuant une opรฉration mathรฉmatique. La division ร  la ligne 14 divise par zรฉro, ce qui provoque systรฉmatiquement une exception ยซ ArithmeticException ยป. Voir ci-dessous :

JUnitClasse de message dans Eclipse avec printMessage divisรฉ par zรฉro ร  la ligne 14

package guru99.junit;

public class JUnitMessage{

	private String message;

	public JUnitMessage(String message) {
		this.message = message;
	}

public void printMessage(){

	System.out.println(message); 
	int divide=1/0;

}

public String printHiMessage(){ 

	message="Hi!" + message;
	
	System.out.println(message);

	return message;
}

}

Code Explication:

  • Code Ligne 7: Crรฉation d'un constructeur paramรฉtrรฉ avec initialisation de champ.
  • Code Ligne 11-14: Crรฉation d'une mรฉthode pour l'opรฉration mathรฉmatique.
  • Code Ligne 18: Crรฉation d'une autre mรฉthode pour imprimer un message.
  • Code Ligne 20: Crรฉation d'une nouvelle chaรฎne pour imprimer un message.
  • Code Ligne 22: Impression du nouveau message crรฉรฉ ร  la ligne 20.

Crรฉons une classe de test pour ce qui prรฉcรจde. Java classe pour vรฉrifier l'exception.

Vous trouverez ci-dessous la classe de test qui teste unitairement l'exception (ici ArithmeticException) levรฉe par l'opรฉration ci-dessus. Java classe:

AirthematicTest.java

La capture d'รฉcran ci-dessous montre le mรชme test dans l'รฉditeur, oรน le fichier est enregistrรฉ sous le nom AirthematicTest1, avec le paramรจtre attendu mis en รฉvidence ร  la ligne 13 :

classe AirthematicTest1 en Eclipse avec @Test(expected = ArithmeticException.class) mis en รฉvidence ร  la ligne 13

package guru99.junit;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class AirthematicTest {

	public String message = "Saurabh";
	
	JUnitMessage junitMessage = new JUnitMessage(message);
	
	@Test(expected = ArithmeticException.class)
	public void testJUnitMessage(){

		System.out.println("Junit Message is printing ");
		junitMessage.printMessage();

	}

	@Test
	public void testJUnitHiMessage(){ 
		message="Hi!" + message;
		System.out.println("Junit Message is printing ");
		assertEquals(message, junitMessage.printHiMessage());
	
	}
}

Code Explication:

  • Code Ligne 13: Nous utilisons l'annotation `@Test` pour crรฉer notre test. Lorsque vous exรฉcutez la mรฉthode de la classe ci-dessus, elle effectue une opรฉration mathรฉmatique. Une exception `ArithmeticException` est attendue ; vous la spรฉcifiez donc comme paramรจtre dans `@Test`.
  • Code Ligne 17: Appel de printMessage() depuis JUnitMessage.java.
  • Code Ligne 21-22: Crรฉation d'une autre mรฉthode de test pour vรฉrifier le message ยซ Salut ยป, cette fois sans paramรจtre attendu.

La classe contient deux mรฉthodes de test, donc une seule exรฉcution les exรฉcute toutes les deux : celle qui sโ€™attend ร  une exception ArithmeticException et celle qui vรฉrifie la chaรฎne de caractรจres renvoyรฉe.

ร€ noter: Cet exemple apparaรฎt sous trois noms diffรฉrents dans le document original : la liste des รฉlรฉments mentionne la classe AirthematicTest, la capture dโ€™รฉcran de lโ€™รฉditeur affiche AirthematicTest1 et lโ€™affichage des rรฉsultats indique JunitTestExample. Le code est identique dans chaque cas ; seul le nom du fichier diffรจre.

Exรฉcutons-le et vรฉrifions le rรฉsultat. JUnit Le rapport ci-dessous indique l'exรฉcution de Exemple de test Junit.java.

Sortie :

Voici le rรฉsultat, qui montre un test rรฉussi sans aucun รฉchec. trace comme indiquรฉ ci-dessous :

Eclipse JUnit Affichage du rapport : Exรฉcutions 2/2 sans erreur ni รฉchec pour JunitTestExample

Les deux mรฉthodes sont validรฉes. La premiรจre rรฉussit car l'exception ArithmeticException qu'elle a dรฉclarรฉe a bien รฉtรฉ levรฉe, et la seconde rรฉussit car la chaรฎne renvoyรฉe correspond. Si la division n'avait jamais รฉtรฉ levรฉe, JUnit la premiรจre mรฉthode aurait รฉchouรฉ avec le message ยซ Exception attendue : java.lang.ArithmeticException ยป.

Trois faรงons de tester une exception dans JUnit 4

Le paramรจtre attendu est le plus court des trois JUnit Il existe quatre expressions idiomatiques, mais ce n'est pas toujours la bonne. Le tableau les compare en fonction des deux questions qui dรฉterminent le choix : pouvez-vous affirmer quoi que ce soit du message, et savez-vous quelle ligne a รฉtรฉ prononcรฉe ?

Approche Affirme le message ? ร‰pingler la ligne de lancer ? Meilleur pour
@Test(attendu = X.class) Non Non, n'importe quelle ligne de la mรฉthode peut gรฉnรฉrer une erreur. Tests courts oรน seul le type d'exception importe.
essayer / รฉchouer() / attraper Oui, ร  l'intรฉrieur du bloc de rรฉception Oui, seule la communication protรฉgรฉe est surveillรฉe. Tests qui doivent examiner le message ou la cause.
@Rule Exception attendue Oui, via expectMessage() Non Les suites logicielles existantes sont dรฉjร  basรฉes sur des rรจgles.

La fonction `fail()` mentionnรฉe dans l'introduction se prรฉsente comme suit : si l'appel ne gรฉnรจre pas d'exception, `fail()` s'exรฉcute et le test renvoie le message que vous avez รฉcrit.

@Test
public void testDivideByZero() {
    try {
        junitMessage.printMessage();
        fail("Expected an ArithmeticException");
    } catch (ArithmeticException e) {
        assertEquals("/ by zero", e.getMessage());
    }
}

La rรจgle ExpectedException se situe entre les deux. Elle a รฉtรฉ dรฉprรฉciรฉe dans JUnit 4.13 en faveur de la mรฉthode assertThrows dรฉcrite ci-aprรจs, donc nouvelle JUnit 4 tests ne devraient pas l'adopter.

Comment tester les exceptions dans JUnit 5 avec assertThrows()

JUnit 5 supprime complรจtement le paramรจtre attendu de @Test. Jupiter fournit assertThrows ()Cette fonction prend en paramรจtres la classe d'exception et une lambda contenant le code testรฉ. Elle renvoie l'exception interceptรฉe, permettant ainsi de rรฉcupรฉrer ultรฉrieurement le message, la cause et tout champ personnalisรฉ.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;

public class AirthematicJupiterTest {

    JUnitMessage junitMessage = new JUnitMessage("Saurabh");

    @Test
    public void testJUnitMessage() {
        ArithmeticException thrown = assertThrows(
                ArithmeticException.class,
                () -> junitMessage.printMessage());
        assertEquals("/ by zero", thrown.getMessage());
    }
}

Trois liens affirmations complรฉter la famille :

  • assertThrows accepte le type d'exception ou toute sous-classe de celui-ci.
  • assertThrowsExactly rejette une sous-classe, donc seul le type nommรฉ est acceptรฉ.
  • assertDoesNotThrow รฉnonce l'attente inverse, ร  savoir que le bloc se termine proprement.

Le JUnit 4 lignes de code sur cette page s'exรฉcutent toujours sur le JUnit La plateforme utilise le moteur d'origine, donc rien de ce qui prรฉcรจde n'a besoin d'รชtre rรฉรฉcrit pour continuer ร  fonctionner pendant la migration d'un projet.

Erreurs courantes lors du test des exceptions dans JUnit

Les tests d'exception รฉchouent de quelques maniรจres facilement identifiables. Chaque ligne indique le symptรดme, la cause et la solution.

Symptรดme Causes Fixer
Exception attendue : java.lang.ArithmeticException La mรฉthode s'est dรฉroulรฉe sans lancer. Vรฉrifiez que l'entrรฉe est bien invalide, puis relancez le programme.
Le test rรฉussit, mais la mauvaise ligne a รฉtรฉ lancรฉe. Le paramรจtre attendu surveille l'intรฉgralitรฉ de la mรฉthode, y compris la configuration. Dรฉplacez la configuration ou utilisez assertThrows autour d'un appel.
Type d'exception non gรฉrรฉe dans l'รฉditeur Une exception vรฉrifiรฉe est levรฉe mais n'est jamais dรฉclarรฉe. Ajoutez des exceptions ร  la signature de la mรฉthode de test.
Le test rรฉussit sur une sous-classe que vous n'aviez pas prรฉvue assertThrows accepte les sous-classes du type nommรฉ. Utilisez assertThrowsExactly pour une correspondance de type stricte.
ยซ expected ยป n'est pas un attribut valide Le test a รฉtรฉ compilรฉ en utilisant l'annotation Jupiter @Test. Importer org.junit.Test pour JUnit 4, ou passez ร  assertThrows.

Cโ€™est la derniรจre ligne qui pose le plus de problรจmes lors dโ€™une migration, car les deux annotations portent le nom @Test et seule lโ€™importation permet de les distinguer. Keeping UN JUnit version par cas de test Cette classe permet d'รฉviter tout le problรจme de classe.

FAQ

Le paramรจtre attendu ne peut pas vรฉrifier un message. Encapsulez l'appel dans un bloc try, appelez fail() immรฉdiatement aprรจs, et effectuez une assertion sur getMessage() dans le bloc catch. JUnit 5 simplifie cela car assertThrows renvoie l'exception interceptรฉe.

JUnit Le test รฉchoue et affiche ยซ Exception attendue ยป suivi de la classe que vous avez spรฉcifiรฉe. Aucun autre message n'est fourni ; un test qui ne gรฉnรจre jamais d'exception est donc identique ร  un test dont le comportement a รฉtรฉ modifiรฉ silencieusement dans le code de production.

Les assistants IA lisent une mรฉthode, listent les entrรฉes qui atteignent chaque instruction `throw` et rรฉdigent un test pour chaque branche. Le rรฉsultat sert de point de dรฉpart : lโ€™assistant dรฉduit le type dโ€™exception du code, de sorte quโ€™une exception incorrecte est fidรจlement reproduite dans le test.

Copilot Le style appliquรฉ sera celui dรฉjร  prรฉsent dans le fichier ; un projet mixte recevra donc un style mixte. Vรฉrifiez la ligne d'importation avant d'accepter une suggestion, car org.junit.Test et org.junit.jupiter.api.Test sont identiques dans l'รฉditeur.

Elle existe toujours, mais elle a รฉtรฉ dรฉprรฉciรฉe en JUnit La version 4.13 n'a jamais รฉtรฉ portรฉe sur Jupiter. Les suites de tests existantes peuvent la conserver ; les nouveaux tests doivent utiliser assertThrows, plus lisible et ne nรฉcessitant pas de champ de rรจgle public.

Oui. Le paramรจtre lambda est un Exรฉcutable, dรฉclarรฉ comme pouvant lever une Throwable ; par consรฉquent, une exception vรฉrifiรฉe ne nรฉcessite pas de clause throws dans la mรฉthode de test elle-mรชme. Il en va de mรชme pourโ€ฆ JUnit 4. Essayer et attraper (expression idiomatique).

La mรฉthode `assertThrows` accepte toute sous-classe du type spรฉcifiรฉ ; par consรฉquent, si elle attend une `RuntimeException`, elle transmet รฉgalement une `NullPointerException`. Utilisez `assertThrowsExactly` lorsque la classe exacte est importante, ou spรฉcifiez le type le plus prรฉcis que vous attendez.

L'exception n'intervient que lorsque l'on fait partie des rรจgles.tract. Tester une exception : la mรฉthode ne promet jamais de lever des verrous en cas de comportement accidentel et rend la refactorisation plus difficile, ce qui va ร  l'encontre du but du test.

Rรฉsumez cet article avec :