Útmutató a Rendszerszabálykönyvtárhoz
1. Áttekintés
Néha egységtesztek írásakor szükség lehet olyan kód tesztelésére, amely közvetlenül kölcsönhatásba lép a Rendszer osztály. Jellemzően olyan alkalmazásokban, mint a parancssori eszközök, amelyek hívnak System.exit vagy közvetlenül olvassa el az argumentumokat System.in.
Ebben az oktatóanyagban megnézzük a Rendszerszabályok nevű, tiszta külső könyvtár leggyakoribb jellemzőit, amely JUnit-szabályokat tartalmaz a kód teszteléséhez, amely a Rendszer osztály.
2. Maven-függőségek
Először tegyük hozzá a Rendszerszabályok függőségét a sajátunkhoz pom.xml:
com.github.stefanbirkner rendszerszabályok 1.19.0
Hozzáadjuk a System Lambda függőséget is, amely a Maven Central-nál is elérhető:
com.github.stefanbirkner system-lambda 1.1.0
Mivel a Rendszerszabályok nem támogatják közvetlenül JUnit5, hozzáadtuk az utolsó függőséget. Ez biztosítja a System Lambda burkoló módszereket a tesztekben. Van ennek kiterjesztés-alapú alternatívája, az úgynevezett Rendszercsonkok.
3. A rendszer tulajdonságainak kezelése
A gyors összefoglalás érdekében a Java platform a Tulajdonságok objektum információt nyújtani a helyi rendszerről és a konfigurációról. Könnyen kinyomtathatjuk a tulajdonságokat:
System.getProperties () .forEach ((kulcs, érték) -> System.out.println (kulcs + ":" + érték));
Mint láthatjuk, a tulajdonságok olyan információkat tartalmaznak, mint az aktuális felhasználó, a Java futásidejének jelenlegi verziója és a fájl elérési útjának elválasztója:
java.version: 1.8.0_221 file.separator: / user.home: / Users / baeldung os.name: Mac OS X ...
A. Segítségével beállíthatjuk saját rendszer tulajdonságait is System.setProperty módszer. Óvatosan kell eljárni, ha tesztjeinkben a rendszer tulajdonságokkal dolgozunk, mivel ezek a tulajdonságok JVM-globálisak.
Például, ha beállítunk egy rendszer tulajdonságot, akkor biztosítanunk kell, hogy a teszt végeztével vagy meghibásodás esetén visszaállítsuk az eredeti értéket. Ez néha nehézkes beállításhoz vezethet, és lebonthatja a kódot. Ha azonban ezt elhanyagoljuk, az váratlan mellékhatásokhoz vezethet tesztjeink során.
A következő szakaszban megnézzük, hogy miként nyújthatjuk be, tisztíthatjuk meg és biztosíthatjuk a rendszer tulajdonságainak visszaállítását, miután a tesztjeink tömören és egyszerűen befejeződtek.
4. Rendszer tulajdonságainak biztosítása
Képzeljük el, hogy van egy rendszer tulajdonságunk log_dir amely tartalmazza a naplók írásának helyét, és az alkalmazás elindításakor beállítja ezt a helyet:
System.setProperty ("log_dir", "/ tmp / baeldung / logs");
4.1. Biztosítson egyetlen ingatlant
Most vegyük figyelembe, hogy egységtesztünk alapján egy másik értéket szeretnénk megadni. Ezt megtehetjük a ProvideSystemProperty szabály:
public class ProvidesSystemPropertyWithRuleUnitTest {@Rule public final ProvideSystemProperty providesSystemPropertyRule = new ProvideSystemProperty ("log_dir", "test / resources"); @Test public void givenProvideSystemProperty_whenGetLogDir_thenLogDirIsProvidedSuccessfully () {assertEquals ("log_dir kell megadni", "teszt / erőforrások", System.getProperty ("log_dir")); } // az egység teszt meghatározása folytatódik}
Használni a ProvideSystemProperty szabály szerint tetszőleges értéket állíthatunk be egy adott rendszertulajdonságra a tesztjeink alapján történő felhasználásra. Ebben a példában a log_dir tulajdon a mi teszt / források könyvtárba, és az egység tesztünkből egyszerűen állítsa be, hogy a teszt tulajdonság értékét sikeresen megadták.
Ha ezután kinyomtatjuk a log_dir tulajdonság, amikor teszt osztályunk teljes:
@AfterClass public static void tearDownAfterClass () dobja a Kivételt {System.out.println (System.getProperty ("log_dir")); }
Láthatjuk, hogy az ingatlan értéke visszaállt az eredeti értékére:
/ tmp / baeldung / logs
4.2. Több tulajdonság biztosítása
Ha több tulajdonságot kell megadnunk, használhatjuk a és módszer annyi tulajdonságérték összekapcsolására, amennyi a tesztünkhöz szükséges:
@Rule public final ProvideSystemProperty providesSystemPropertyRule = new ProvideSystemProperty ("log_dir", "test / resources"). És ("another_property", "another_value")
4.3. Tulajdonságok megadása fájlból
Hasonlóképpen lehetőségünk van tulajdonságokat megadni egy fájlból vagy osztályútvonal erőforrásból a ProvideSystemProperty szabály:
@Rule public final ProvideSystemProperty providesSystemPropertyFromFileRule = ProvideSystemProperty.fromResource ("/ test.properties"); @Test public void givenProvideSystemPropertyFromFile_whenGetName_thenNameIsProvidedSuccessfully () {assertEquals ("a nevet meg kell adni", "baeldung", System.getProperty ("név")); assertEquals ("verziót kell megadni", "1.0", System.getProperty ("verzió")); }
A fenti példában feltételezzük, hogy van egy teszt.tulajdonságok fájl az osztályúton:
név = baeldung verzió = 1.0
4.4. Tulajdonságok biztosítása a JUnit5 és a Lambdas használatával
Mint korábban említettük, a könyvtár System Lambda verzióját is felhasználhatjuk a JUnit5-tel kompatibilis tesztek végrehajtására.
Nézzük meg, hogyan lehet végrehajtani tesztünket a könyvtár ezen verziójával:
@BeforeAll static void setUpBeforeClass () dobja a {System.setProperty ("log_dir", "/ tmp / baeldung / logs" kivételt); } @Test void givenSetSystemProperty_whenGetLogDir_thenLogDirIsProvidedSuccessfully () dobja a {Kivétel {restoreSystemProperties (() -> {System.setProperty ("log_dir", "teszt / erőforrások"); assertEquals ("log_dir erőforrásokat kell biztosítani", "test.getProp", "test.getProp", "test.getProp", "test.getProp", "test.getProp", "test.getProp", "test.getProp", "test.getProp", "test.getProp", "test.getProp /" rendszer ("log_dir"));}); assertEquals ("log_dir kell megadni", "/ tmp / baeldung / logs", System.getProperty ("log_dir")); }
Ebben a verzióban használhatjuk a restoreSystemProperties módszer egy adott utasítás végrehajtására. Ebben a nyilatkozatban beállíthatjuk és megadhatjuk a rendszer tulajdonságaihoz szükséges értékeket. Amint láthatjuk, miután ez a módszer befejezte a végrehajtást, a log_dir ugyanaz, mint korábban / tmp / baeldung / logs.
Sajnos nincs beépített támogatás a tulajdonságokat fájlokból a restoreSystemProperties módszer.
5. A rendszer tulajdonságainak törlése
Előfordulhat, hogy a teszt megkezdésekor törölni szeretnénk a rendszer tulajdonságainak halmazát, és a teszt befejezése után visszaállíthatjuk eredeti értékeiket, függetlenül attól, hogy az sikeres-e vagy sem.
Használhatjuk a ClearSystemProperties szabály erre a célra:
@Rule public final ClearSystemProperties userNameIsClearedRule = új ClearSystemProperties ("felhasználónév"); @Test public void givenClearUsernameProperty_whenGetUserName_thenNull () {assertNull (System.getProperty ("felhasználónév")); }
A rendszer tulajdonság felhasználónév az egyik előre definiált rendszertulajdonság, amely tartalmazza a felhasználói fiók nevét. A fenti egységtesztnek megfelelően, töröljük ezt a tulajdonságot, és ellenőrizzük, hogy üres-e a tesztünkből.
Kényelmesen több tulajdonságnevet is átadhatunk a ClearSystemProperties konstruktőr.
6. Gúnyolódás System.in
Időről időre létrehozhatunk interaktív parancssori alkalmazásokat, amelyekből olvasni lehet System.in.
Ebben a szakaszban egy nagyon egyszerű példát fogunk használni, amely kiolvassa a keresztnevet és a vezetéknevet a szokásos bemenetből, és összefűzi őket:
privát karakterlánc getFullname () {try (Szkenner szkenner = új Szkenner (System.in)) {String keresztnév = szkenner.next (); Karakterlánc vezetéknév = szkenner.next (); return String.join ("", keresztnév, vezetéknév); }}
A Rendszerszabályok tartalmazzák a TextFromStandardInputStream szabály, amellyel megadhatjuk azokat a vonalakat, amelyeket meg kell adni a híváskor System.in:
@Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream (); @Test public void givenTwoNames_whenSystemInMock_thenNamesJoinedTogether () {systemInMock.provideLines ("Jonathan", "Cook"); assertEquals ("A neveket összefűzni kell", "Jonathan Cook", getFullname ()); }
Ezt a providesLines metódus, amely egy varargs paramétert vesz igénybe egynél több érték megadásához.
Ebben a példában két értéket adunk meg, mielőtt meghívnánk a getFullname módszer, ahol System.in hivatkozik. A két megadott vonalértékünk minden alkalommal visszaadódik, amikor hívunk scanner.next ().
Vizsgáljuk meg, hogyan érhetjük el ugyanezt a teszt JUnit 5 verziójában a System Lambda segítségével:
@Test void givenTwoNames_whenSystemInMock_thenNamesJoinedTogether () dobja a (z) {Kivételt a withTextFromSystemIn ("Jonathan", "Cook"). Végrehajtás (() -> {assertEquals ("A neveket összefűzni kell", "Jonathan Cook", getFullname ())}; }
Ebben a variációban a hasonló nevűeket használjuk withTextFromSystemIn módszer, amely lehetővé teszi számunkra a megadott megadását System.in értékek.
Fontos megemlíteni mindkét esetben, hogy a teszt befejezése után a System.in helyreállítják.
7. Tesztelés System.out és System.err
Egy korábbi oktatóanyagban láttuk, hogyan lehet a rendszerszabályokat használni az egység teszteléséhez System.out.println ().
Kényelmesen majdnem azonos megközelítést alkalmazhatunk a kód tesztelésére, amely kölcsönhatásba lép a szokásos hibasorral. Ezúttal a SystemErrRule:
@Rule public final SystemErrRule systemErrRule = new SystemErrRule (). EnableLog (); @Test public void givenSystemErrRule_whenInvokePrintln_thenLogSuccess () {printError ("Hiba történt a Baeldung olvasóknál !!"); Assert.assertEquals ("Hiba történt a Baeldung olvasóknál !!", systemErrRule.getLog (). Trim ()); } private void printError (karakterlánc kimenet) {System.err.println (output); }
Szép! Használni a SystemErrRule, elfoghatjuk az írásokat System.err. Először elkezdünk naplózni mindent, amire írtunk System.err felhívásával a enableLog módszer a szabályunkon. Akkor egyszerűen hívunk getLog hogy a szöveget a System.err-be írjuk, mióta hívtuk enableLog.
Most hajtsuk végre tesztünk JUnit5 verzióját:
@Test void givenTapSystemErr_whenInvokePrintln_thenOutputIsReturnedSuccessfully () dobja a Kivételt {String text = tapSystemErr (() -> {printError ("Hiba történt Baeldung Readers !!");}); Assert.assertEquals ("Hiba történt a Baeldung Readers !!", text.trim ()); }
Ebben a verzióban felhasználjuk a csapSystemErr metódus, amely végrehajtja az utasítást, és lehetővé teszi a továbbított tartalom rögzítését System.err.
8. Kezelés System.exit
A parancssori alkalmazások általában hívással zárulnak le System.exit. Ha tesztelni szeretnénk egy ilyen alkalmazást, akkor valószínűleg tesztünk rendellenesen leáll, mielőtt befejezné, amikor találkozik a hívó kóddal System.exit.
Szerencsére a Rendszerszabályok elegáns megoldást kínálnak ennek kezelésére a ExpectedSystemExit szabály:
@Rule public final ExpectedSystemExit exitRule = ExpectedSystemExit.none (); @Test public void givenSystemExitRule_whenAppCallsSystemExit_thenExitRuleWorkssAsExpected () {exitRule.expectSystemExitWithStatus (1); kijárat(); } private void exit () {System.exit (1); }
Használni a ExpectedSystemExit szabály lehetővé teszi számunkra, hogy tesztünkből meghatározzuk a várható értéket System.exit () hívás. Ebben az egyszerű példában a várható állapotkódot is ellenőrizzük a VárjSystemExitWithStatus módszer.
Valami hasonlót érhetünk el a JUnit 5 verziónkban a catchSystemExit módszer:
@Test void givenCatchSystemExit_whenAppCallsSystemExit_thenStatusIsReturnedSuccessfully () dobja az {int statusCode = catchSystemExit (() -> {exit ();}) kivételet; assertEquals ("az állapotkód legyen 1:", 1, statusCode); }
9. Következtetés
Összefoglalva, ebben az oktatóanyagban részletesen feltártuk a Rendszerszabályok könyvtárat.
Először azzal kezdtük, hogy elmagyarázzuk a rendszer tulajdonságait használó kód tesztelését. Ezután megvizsgáltuk, hogyan teszteljük a standard kimenetet és a standard bemenetet. Végül megvizsgáltuk, hogyan kezeljük a hívó kódokat System.exit tesztjeinkből.
A System Rules könyvtár támogatást nyújt környezeti változók és speciális biztonsági szempontok biztosításához is tesztjeinkből. A részletekről feltétlenül nézze meg a teljes dokumentációt.
Mint mindig, a cikk teljes forráskódja elérhető a GitHubon.