JUnit Várható kivételteszt: @Test(várható)

⚡ Okos összefoglaló

JUnit A kivételtesztelés megerősíti, hogy egy metódus a várt hibát dobja-e, a @Test annotáció opcionális várt paraméterének használatával. JUnit 4 és az assertThrows metódus a JUnit 5.

  • 🔘 Cél: Bizonyítsuk be, hogy az érvénytelen bemenet dokumentált kivételt eredményez egy csendes rossz válasz helyett.
  • ☑️ Syntax: A @Test(várható = ArithmeticException.class) csak akkor sikeres, ha pontosan az adott típusú kivétel keletkezik.
  • Példa: JUnitAz üzenet nullával oszt, és az AirthematicTest az eredményül kapott ArithmeticException-t várja.
  • 🧪 alternatíva: Egy fail() által követett try blokk lehetővé teszi a kapott kivétel vizsgálatát, mielőtt azt aktiválnánk.
  • 🇧🇷 JUnit 5: Az assertThrows visszaadja a kapott kivételt, így az üzenet és az ok is feltüntethető.
  • 📌 Csapda: A várt paraméter mindenhol átadódik, ahol a kivétel történik, ami elrejtheti a beállítási kód hibáját.

JUnit várható kivételteszt a @Test(várható) paraméter használatával

JUnit lehetőséget biztosít arra, hogy traca kivételt, és azt is ellenőrzi, hogy a kód a várt kivételt dobja-e vagy sem.

JUnit A 4. számú verzió egyszerű és olvasható módszert kínál a kivételek teszteléséhez. Használhatja a következőket:

  • A(z) opcionális paraméter (elvárt) @Test annotációés
  • Nak nek tracAz információ kiküszöbölésére a „fail()” használható.

Míg tesztelés kivétel esetén gondoskodnia kell arról, hogy a kivételosztály, amelyet a függvény opcionális paraméterében megad, @Test annotáció ugyanaz, amit a metódus valójában dob. Ez azért van, mert kivételt vársz a használt metódustól. egység tesztelés; különben a miénk JUnit teszt sikertelen lenne.

Példa: @Test(várt = IllegalArgumentException.class)

A „várható” paraméter használatával megadhatja a teszt által dobott kivétel nevét. A fenti példában a következőt használja: „Érvénytelen argumentumkivétel„, amelyet a teszt dob, ha a fejlesztő nem engedélyezett argumentumot használ.

Példa a @Test(várható) függvény használatára

Értsük meg a kivételtesztelést egy Java osztály egy olyan metódussal, amely egy kivételEgy tesztórán fogod kezelni és tesztelni. Gondold át JUnitMessage.java, amelynek van egy matematikai műveletet végrehajtó metódusa. A 14. sorban található osztás nullával oszt, így a metódus mindig „ArithmeticException” kivételt dob. Lásd alább:

JUnitÜzenet osztály Eclipse a printMessage nullával való osztásával a 14. sorban

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 Magyarázat:

  • Code 7 vonal: Paraméterezett konstruktor létrehozása mező inicializálásával.
  • Code 11-14. sor: Matematikai művelethez metódus létrehozása.
  • Code 18 vonal: Másik módszer létrehozása üzenet nyomtatásához.
  • Code 20 vonal: Új karakterlánc létrehozása üzenet nyomtatásához.
  • Code 22 vonal: A 20. sorban létrehozott új üzenet kinyomtatása.

Hozzunk létre egy tesztosztályt a fentiekhez Java osztály a kivétel ellenőrzéséhez.

Lásd alább a tesztosztályt, amelyik egység teszteli a fentiekből kiváltott kivételt (itt ArithmeticException). Java osztály:

AirthematicTest.java

Az alábbi képernyőkép ugyanazt a tesztet mutatja a szerkesztőben, ahol a fájl AirthematicTest1 néven van mentve, a várt paraméterrel a 13. sorban:

AirthematicTest1 osztály Eclipse a 13. sorban kiemelve a @Test(várható = ArithmeticException.class) függvényt

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 Magyarázat:

  • Code 13 vonal: A @Test annotáció használatával hozzuk létre a tesztünket. A fenti osztály metódusának végrehajtásakor egy matematikai műveletet fogunk meghívni. Itt az ArithmeticException várható, ezért paraméterként adjuk meg a @Test-ben.
  • Code 17 vonal: A printMessage() meghívása innen: JUnitÜzenet.java.
  • Code 21-22. sor: Egy másik tesztmetódus létrehozása a Hi üzenet ellenőrzésére, ezúttal várható paraméter nélkül.

Az osztály két tesztmetódust tartalmaz, így egyetlen futtatás mindkettőt végrehajtja: azt, amelyik ArithmeticException-t vár, és azt, amelyik a visszaadott karakterláncra állítja be az értéket.

Jegyzet: Ez a példa az eredeti anyagban három néven szerepel – a lista az AirthematicTest osztályt hívja, a szerkesztő képernyőképe az AirthematicTest1 osztályt mutatja, az eredménynézet pedig a JunitTestExample nevet mutatja. A kód mindegyikben megegyezik; csak a fájlnév különbözik.

Hajtsuk végre és ellenőrizzük az eredményt. JUnit lásd az alábbi jelentéseket a futamról JunitTestPélda.java.

output:

Itt látható a kimenet, amely egy sikeres tesztet mutat hibák nélkül trace az alábbiak szerint:

Eclipse JUnit jelentések megtekintése 2/2-én fut nulla hibával és nulla meghibásodással a JunitTestExample számára

Mindkét metódus zöld. Az első azért megy át, mert a deklarált ArithmeticException megérkezett, a második pedig azért, mert a visszaadott karakterlánc egyezik. Ha az osztás soha nem lett volna végrehajtva, JUnit az első metódus a következő üzenettel hibát jelzett volna: „Várható kivétel: java.lang.ArithmeticException”.

Három módszer a kivétel tesztelésére JUnit 4

A várható paraméter a három közül a legrövidebb. JUnit 4 idióma létezik, de nem mindig ez a helyes. A táblázat összehasonlítja őket a választást eldöntő két kérdés alapján: tudod-e állítani az üzenetet, és tudod-e, melyik sort dobta?

Megközelítés Megerősíti az üzenetet? Rögzíti a dobóvonalat? A legjobb
@Test(elvárt = X.osztály) Nem Nem — a metódus bármely sora dobhat Rövid tesztek, ahol csak a kivétel típusa számít.
próbálkozás / kudarc() / elkapás Igen, a fogóblokkon belül Igen – csak a védett hívást figyelik Tesztek, amelyeknek az üzenetet vagy az okot kell megvizsgálniuk.
@Rule VárhatóKivétel Igen, az expectMessage() függvényen keresztül Nem A hagyományos csomagok már szabályokra épülnek.

A bevezetőben említett fail() kifejezés így néz ki. Ha a hívás nem dob hibát, a fail() lefut, és a teszt a megadott üzenetet jeleníti meg:

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

Az ExpectedException szabály a kettő között helyezkedik el. 2018-ban elavulttá vált. JUnit 4.13 a később ismertetett assertThrows metódus javára, tehát új JUnit 4 tesztnek nem szabadna alkalmaznia.

Kivételek tesztelése a következőben: JUnit 5 az assertThrows() függvénnyel

JUnit Az 5-ös érték teljesen eltávolítja a várt paramétert a @Test-ből. A Jupiter biztosítja a megfelelő paramétert. assertThrows(), amely a kivételosztályt és a tesztelt kódot tartalmazó lambda függvényt veszi alapul. Visszaadja az elkapott kivételt, így az üzenet, az ok és bármilyen egyéni mező utólag beállítható.

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

Három kapcsolódó állítások kerekítsd ki a családot:

  • assertThrows elfogadja a kivétel típusát vagy annak bármely alosztályát.
  • assertThrowsExactly elutasít egy alosztályt, így csak a megnevezett típus fogadható el.
  • assertDoesNotThrow az ellenkező elvárást fejezi ki, miszerint a blokk tisztán fejeződik be.

Az JUnit Az ezen az oldalon található 4-es kód továbbra is fut a JUnit Platform a vintage motoron keresztül, így a fentieket nem kell átírni ahhoz, hogy működjön a projekt migrálása közben.

Gyakori hibák a kivételek tesztelésekor JUnit

A kivételtesztek néhány felismerhető módon buknak meg. Minden sor megnevezi a tünetet, az okot és a megoldást.

Tünet Okoz Rögzít
Várt kivétel: java.lang.ArithmeticException A módszer dobás nélkül fejeződött be. Ellenőrizd, hogy a bemenet valóban érvénytelen-e, majd futtasd újra.
A teszt sikerült, de rossz vonalat húztak. A várt paraméter a teljes metódust figyeli, beleértve a beállítást is. Mozgasd ki a beállítást, vagy válts assertThrows használatára egyetlen hívás körül.
Kezeletlen kivétel típusa a szerkesztőben Egy ellenőrzött kivétel keletkezik, de soha nem deklarálják. Adj hozzá throw-okat a tesztmetódus aláírásához.
A teszt sikeresen teljesített egy nem kívánt alosztályon Az assertThrows elfogadja a megnevezett típusú alosztályokat. Szigorú típusegyeztetéshez használd az assertThrowsExactly metódust.
A várt attribútum nem érvényes A tesztet a Jupiter @Test annotáció alapján fordították. Importálja az org.junit.Test fájlt a következőhöz: JUnit 4, vagy lépj az assertThrows-hoz.

Az utolsó sor az, ami a legtöbb embert megragadja a migráció során, mivel mindkét annotáció neve @Test, és csak az importálás teszi őket megkülönböztethetővé. Keeping egy JUnit verzió szerint próbaper Az osztály elkerüli a probléma egész osztályát.

GYIK

A várt paraméter nem tud üzenetet ellenőrizni. Csomagold a hívást egy try blokkba, hívd meg a fail() függvényt közvetlenül utána, és állítsd be a getMessage() függvényt a catch blokkon belül. JUnit Az 5-ös verzió ezt leegyszerűsíti, mivel az assertThrows visszaadja a fogott kivételt.

JUnit megbukik a teszten, és a „Várható kivétel” üzenetet adja, majd a megnevezett osztályt. Semmi mást nem jelent, így egy soha nem dobó teszt ugyanúgy néz ki, mint amelyiknek a termelési kódja csendben megváltoztatta a viselkedését.

Az MI asszisztensek beolvasnak egy metódust, listázzák az egyes throw utasításokhoz tartozó bemeneteket, és áganként tesztet készítenek. A kimenetet kiindulópontként kezelik: az asszisztens a kódból következteti ki a kivétel típusát, így a rossz throw hűen bemásolódik a tesztbe.

Másodpilóta a fájlban már létező stílust követi, így egy vegyes projekt mixet kap. Javaslat elfogadása előtt ellenőrizze az import sort, mert az org.junit.Test és az org.junit.jupiter.api.Test azonosnak tűnik a szerkesztőben.

Még mindig létezik, de 2000-ben elavulttá tették. JUnit 4.13-as verzióra, és soha nem került át Jupiterre. A meglévő csomagok megtarthatják; az új teszteknek az assertThrows függvényt kell használniuk, amely jobban olvasható és nem igényel nyilvános szabálymezőt.

Igen. A lambda paraméter egy végrehajtható fájl, amelyet úgy deklarálnak, hogy „throwable”-t dobjon, tehát egy ellenőrzött kivételhez nincs szükség „throws” záradékra magán a tesztmetóduson. Ugyanez igaz a következőre is: JUnit 4 próbáld meg elkapni az idiómát.

Az assertThrows függvény a megnevezett típus bármely alosztályát elfogadja, így a RuntimeException elvárása a NullPointerException-t is átadja. Használd az assertThrowsExactly függvényt, ha a pontos osztály számít, vagy nevezd meg a legszűkebb elvárt típust.

Csak akkor, ha a kivétel a kontraindikátor része.tract. Kivétel tesztelése során a metódus soha nem ígér zárolásokat véletlen viselkedés esetén, és megnehezíti a refaktorálást, ami ellentétes a teszt értelmével.

Foglald össze ezt a bejegyzést a következőképpen: