A DBUnit bemutatása

1. Bemutatkozás

Ebben az oktatóanyagban megnézzük a szokásos egységtesztelő eszközt, a DBUnit tesztrelációs adatbázis interakciók ban ben Jáva.

Meglátjuk, hogyan segít az adatbázisunk ismert állapotba kerülni és érvényesülni egy várható állapot ellen.

2. Függőségek

Először hozzáadhatjuk a DBUnit projektünkhöz a Maven Central-tól a dbunit függőség a mi pom.xml:

 org.dbunit dbunit 2.7.0 teszt 

A legújabb verziót megkereshetjük a Maven Central-on.

3. Hello World példa

Ezután definiáljuk a adatbázis séma:

schema.sql:

TÁBLÁZAT LÉTREHOZÁSA, HA NEM LÉTEZIK AZ ÜGYFELEKET (`id` int AUTO_INCREMENT NOT NULL,` first_name` varchar (100) NOT NULL, `last_name` varchar (100) NOT NULL, PRIMARY KEY (` id`)); TÁBLÁZAT LÉTREHOZÁSA, HA NEM LÉTEZIK ELEMEK (`id` int AUTO_INCREMENT NOT NULL,` title` varchar (100) NOT NULL, `producer` dátum,` price float, PRIMARY KEY (`id`)); 

3.1. A kezdeti adatbázis tartalmának meghatározása

A DBUnit segítségével egyszerűen definiálhatjuk és betölthetjük tesztadatkészletünketdeklaratív módon.

Minden táblázatsort egy XML elemmel határozunk meg, ahol a címke neve egy táblanév, és az attribútumnevek és az értékek az oszlopnevekhez és az értékekhez kapcsolódnak. A soradatok több táblához is létrehozhatók. Meg kell valósítanunk a getDataSet () a metódusa DataSourceBasedDBTestCase a kezdeti adathalmaz definiálásához, ahol használhatjuk a FlatXmlDataSetBuilder hivatkozni az XML fájlunkra:

data.xml:

3.2. Az adatbázis-kapcsolat és a séma inicializálása

Most, hogy megvan a sémánk, inicializálnunk kell az adatbázisunkat.

Ki kell terjesztenünk a DataSourceBasedDBTestCase osztály és inicializálja az adatbázis sémát abban getDataSource () módszer:

DataSourceDBUnitTest.java:

public class DataSourceDBUnitTest kiterjeszti a DataSourceBasedDBTestCase {@Orride védett DataSource getDataSource () {JdbcDataSource dataSource = új JdbcDataSource (); dataSource.setURL ("jdbc: h2: mem: alapértelmezett; DB_CLOSE_DELAY = -1; init = runcript a 'classpath: schema.sql'" -ből); dataSource.setUser ("sa"); dataSource.setPassword ("sa"); return dataSource; } @Orride védett IDataSet getDataSet () dobja a Kivételt {return new FlatXmlDataSetBuilder (). Build (getClass (). GetClassLoader () .getResourceAsStream ("data.xml")); }}

Itt egy SQL fájlt továbbítottunk egy H2 memóriabelső adatbázisba annak kapcsolati karakterláncában. Ha más adatbázisokon akarunk tesztelni, meg kell adnunk az egyedi megvalósításunkat hozzá.

Tartsd észben, hogy, példánkban A DBUnit minden tesztmódszer végrehajtása előtt újra inicializálja az adatbázist a megadott tesztadatokkal.

Ennek többféle módon konfigurálható a via kapSetUpOperation és kapTearDownOperation:

@Orride védett DatabaseOperation getSetUpOperation () {return DatabaseOperation.REFRESH; } @Orride védett DatabaseOperation getTearDownOperation () {return DatabaseOperation.DELETE_ALL; }

A FRISSÍTÉS műveletet, felszólítja a DBUnit-t, hogy frissítse az összes adatot. Ez biztosítja, hogy minden gyorsítótár kiürül, és az egység tesztünk nem befolyásolja egy másik egység tesztet. A MINDET TÖRÖLNI A művelet biztosítja, hogy minden adat eltávolításra kerül az egyes tesztek végén. Esetünkben elmondjuk a DBUnit-nek, hogy a beállítás során a getSetUpOperation metódus megvalósításakor frissítjük az összes gyorsítótárat. Végül azt mondjuk a DBUnit-nek, hogy távolítsa el az összes adatot a lebontási művelet során a getTearDownOperation módszer megvalósítása.

3.3. A várható állapot és a tényleges állapot összehasonlítása

Most vizsgáljuk meg a tényleges tesztesetünket. Ehhez az első teszthez egyszerűek leszünk - betöltjük a várható adatállományt, és összehasonlítjuk a DB kapcsolatunkról letöltött adatkészlettel:

@Test public void givenDataSetEmptySchema_whenDataSetCreated_thenTablesAreEqual () dobja a Kivételt {IDataSet várhatóDataSet = getDataSet (); ITable várhatóTábla = várhatóDataSet.getTable ("ÜGYFÉLEK"); IDataSet databaseDataSet = getConnection (). CreateDataSet (); ITable actualTable = databaseDataSet.getTable ("ÜGYFÉLEK"); assertEquals (vártTábla, ténylegesTáblázat); }

4. Mély merülés Állítások

Az előző szakaszban láttunk egy alapvető példát a táblázat tényleges tartalmának és egy várható adatsor összehasonlítására. Most felfedezzük a DBUnit támogatását az állítások testreszabásához.

4.1. Érvényesítés SQL lekérdezéssel

A tényleges állapot ellenőrzésének egyszerű módja egy SQL lekérdezés.

Ebben a példában egy új rekordot illesztünk be az ÜGYFELEK táblába, majd ellenőrizzük az újonnan létrehozott sor tartalmát. A várható outputot ben határoztuk meg külön XML fájlt, és kibontotta a tényleges sorértéket egy SQL lekérdezéssel:

@Test public void givenDataSet_whenInsert_thenTableHasNewClient () dobja a (z) {try (InputStream is = getClass (). GetClassLoader (). GetResourceAsStream ("dbunit / várható-felhasználói.xml")) {IDataSet várhatóDataSet = új FlatXu. ITable várhatóTábla = várhatóDataSet.getTable ("ÜGYFÉLEK"); Connection conn = getDataSource (). GetConnection (); conn.createStatement () .executeUpdate ("INSERT INTO CLIENTS (first_name, last_name) VALUES ('John', 'Jansen')"); ITable actualData = getConnection () .createQueryTable ("eredmény_neve", "KIVÁLASZTÁS * AZ ÜGYFÉLEKBŐL WHERE last_name =" Jansen ""); assertEqualsIgnoreCols (várhatóTábla, ténylegesData, új karakterlánc [] {"id"}); }}

A getConnection () módszere DBTestCase ancestor class az adatforrás kapcsolat DBUnit-specifikus ábrázolását adja vissza (an IDatabaseConnection példa). A createQueryTable () módszere IDatabaseConnection felhasználható a tényleges adatok lekérésére az adatbázisból, összehasonlítva a várható adatbázis-állapottal, a Assertion.assertEquals () módszer. Az SQL lekérdezés továbbadódott createQueryTable () az a lekérdezés, amelyet tesztelni akarunk. Visszaadja a asztal például, amelyet állításunkra használunk.

4.2. Az oszlopok figyelmen kívül hagyása

Néha az adatbázis-tesztek során figyelmen kívül akarjuk hagyni a tényleges táblák egyes oszlopait. Ezek általában automatikusan generált értékek, amelyeket nem tudunk szigorúan ellenőrizni generált elsődleges kulcsok vagy aktuális időbélyegek.

Ezt megtehetnénk az oszlopok kihagyásával az SQL lekérdezések SELECT záradékaiból, de a DBUnit kényelmesebb segédprogramot kínál ennek eléréséhez. A statikus módszerekkel DefaultColumnFilter osztályban létrehozhatunk egy újat ITable példány egy meglévőből, az oszlopok egy részének kizárásával, az itt látható módon:

@Test public void givenDataSet_whenInsert_thenGetResultsAreStillEqualIfIgnoringColumnsWithDifferProduced () dobja a Kivételt {Connection connection = tester.getConnection (). GetConnection (); Karakterlánc [] kizártColumns = {"id", "előállított"}; try (Az InputStream = getClass (). getClassLoader () .getResourceAsStream ("dbunit / várható-figyelmen kívül hagyó-regisztrált_at.xml")) {IDataSet várhatóDataSet = új FlatXmlDataSetBuilder (). build (is); ITable vártábla = kizártColumnsTable (vártDataSet.getTable ("ITEMS"), kizártColumnok); connection.createStatement () .executeUpdate ("INSERT INTO ITS (cím, ár, előállított) ÉRTÉKEK ('Nyaklánc', 199.99, most ())"); IDataSet databaseDataSet = tester.getConnection (). CreateDataSet (); ITable actualTable = kizártColumnsTable (databaseDataSet.getTable ("ITEMS"), kizártColumns); assertEquals (vártTábla, ténylegesTáblázat); }}

4.3. Többszörös hiba kivizsgálása

Ha a DBUnit hibás értéket talál, akkor azonnal egy AssertionError.

Konkrét esetekben használhatjuk a DiffCollectingFailureHandler osztály, amelyet átadhatunk a Assertion.assertEquals () módszer harmadik érvként.

Ez a hibakezelő összegyűjti az összes hibát ahelyett, hogy az elsőre állna, ami azt jelenti a Assertion.assertEquals () módszer mindig sikeres lesz, ha a DiffCollectingFailureHandler. Ezért programozottan ellenőriznünk kell, hogy a kezelő hibát talált-e:

@Test public void givenDataSet_whenInsertUnexpectedData_thenFailOnAllUnexpectedValues ​​() dobja a Kivételt {try (InputStream is = getClass (). GetClassLoader () .getResourceAsStream ("dbunit / várható-többszörös-meghibásodások.xml") {ID (várható) FlatData (várt) (új) ); ITable várható Tábla = várhatóDataSet.getTable ("ITEMS"); Connection conn = getDataSource (). GetConnection (); DiffCollectingFailureHandler collectHandler = új DiffCollectingFailureHandler (); conn.createStatement () .executeUpdate ("INSERT INTO ITEMS (cím, ár) ÉRTÉKEK ('Battery', '1000000')"); ITable actualData = getConnection (). CreateDataSet (). GetTable ("ITEMS"); assertEquals (várhatóTábla, ténylegesData, gyűjtőkezelő); if (! collectHandler.getDiffList (). isEmpty ()) {String üzenet = (String) gyűjtőHandler.getDiffList () .stream () .map (d -> formatDifference ((Difference) d)) .collect (csatlakozás ("\ n ")); logger.error (() -> üzenet); }}} private static String formatDifference (Difference diff) {return "Várható érték a" + diff.getExpectedTable () .getTableMetaData () .getTableName () + "" értékben. " + diff.getColumnName () + "sor" + diff.getRowIndex () + ":" + diff.getExpectedValue () + ", de a következő volt:" + diff.getActualValue (); }

Ezenkívül a kezelő a hibákat az alábbiak formájában biztosítja Különbség példányok, amely lehetővé teszi a hibák formázását.

A teszt futtatása után formázott jelentést kapunk:

java.lang.AssertionError: várható érték az ITEMS.ár 5. sorban: 199,99, de a következő volt: 1000000.0 várható érték az ITEMS-ben. 5. előállított sor: 2019-03-23, de az: várt érték null volt az ITEMS. 5. címsorában: Nyaklánc , de volt: Akkumulátor a com.baeldung.dbunit.DataSourceDBUnitTest.givenDataSet_whenInsertUnexpectedData_thenFailOnAllUnexpectedValues ​​(DataSourceDBUnitTest.java:91)

Fontos észrevenni, hogy ekkor arra számítottunk, hogy az új termék ára 199,99, de 1000000,0 volt. Aztán látjuk, hogy a gyártási dátum 2019-03-23 ​​lesz, de végül semmis volt. Végül a várható elem egy nyaklánc volt, ehelyett kaptunk egy elemet.

5. Következtetés

Ebben a cikkben azt láttuk, hogy a DBUnit hogyan nyújtja a a vizsgálati adatok meghatározásának deklaratív módja nak nek tesztelje a Java alkalmazások adatelérési rétegeit.

Mint mindig, a példák teljes forráskódja elérhető a GitHubon.