Útmutató a JMockit elvárásaihoz

1. Bevezetés

Ez a cikk a JMockit sorozat második része. Érdemes elolvasnia az első cikket, mivel feltételezzük, hogy Ön már ismeri a JMockit alapjait.

Ma elmélyülünk, és az elvárásokra koncentrálunk. Megmutatjuk, hogyan definiálhatunk specifikusabb vagy általánosabb argumentumillesztést és fejlettebb módszereket az értékek meghatározására.

2. Argumentumértékek egyezése

A következő megközelítések egyaránt vonatkoznak Elvárások továbbá Ellenőrzések.

2.1. „Bármely” mezők

A JMockit számos segédmezőt kínál az argumentumillesztés általánosabbá tételéhez. Az egyik ilyen segédprogram a anyX mezők.

Ezek ellenőrzik, hogy bármelyik értéket átadták-e, és minden egyes primitív típushoz (és a megfelelő burkolóosztályhoz) tartozik-e egy, a karakterláncokhoz egy és egy típusú "univerzális" -hoz. Tárgy.

Lássunk egy példát:

nyilvános felület ExpectationsCollaborator {String methodForAny1 (String s, int i, logikai b); void methodForAny2 (hosszú l, lst lista); } @Test public void test (@Mocked ExpectationsCollaborator gúny) dobja a {new Expectations () {{mock.methodForAny1 (anyString, anyInt, anyBoolean) kivételt; eredmény = "bármely"; }}; Assert.assertEquals ("bármilyen", mock.methodForAny1 ("barfooxyz", 0, Boolean.FALSE)); mock.methodForAny2 (2L, új ArrayList ()); új FullVerifications () {{mock.methodForAny2 (anyLong, (List) any); }}; }

A. Használatakor ezt figyelembe kell vennie Bármi mezőbe, át kell adnia a várt típusra. A mezők teljes listája megtalálható a dokumentációban.

2.2. „With” módszerekkel

A JMockit számos metódust is kínál az általános argumentumillesztéshez. Ezek azok withX mód.

Ezek egy kicsit fejlettebb illesztést tesznek lehetővé, mint a anyX mezők. Itt láthatunk egy példát, amelyben meghatározunk egy elvárást egy olyan metódusra, amelyet egy tartalmazó karakterlánc vált ki foo, egy egész szám, amely nem egyenlő 1-vel, egy nem null Logikai és a Lista osztály:

nyilvános felület ExpectationsCollaborator {String methodForWith1 (String s, int i); void methodForWith2 (logikai b, l lista); } @Test public void testForWith (@Mocked ExpectationsCollaborator gúny) kiveti az {új várakozások () {{mock.methodForWith1 (withSubstring ("foo"), withNotEqual (1)) kivételt; eredmény = "vele"; }}; assertEquals ("with", mock.methodForWith1 ("barfooxyz", 2)); mock.methodForWith2 (Boolean.TRUE, új ArrayList ()); új ellenőrzések () {{mock.methodForWith2 (withNotNull (), withInstanceOf (List.class)); }}; }

Láthatja a teljes listát withX módszerek a JMockit dokumentációjában.

Vegye figyelembe, hogy a különleges (Küldött) és withArgThat (Matcher) saját alfejezetük foglalkozik.

2.3. A Null nem Null

Valami, amit jó előbb-utóbb megérteni, az nulla nem használható olyan argumentum meghatározására, amelyre nulla gúnynak adták át.

Tulajdonképpen, nulla néven használják szintaktikus cukor annak meghatározása, hogy bármely objektum át lesz adva (tehát csak referencia típusú paraméterekhez használható). Annak konkrét ellenőrzésére, hogy egy adott paraméter megkapja-e a nulla hivatkozás, az withNull () matcher használható.

A következő példában meghatározzuk egy makett viselkedését, amelyet akkor kell kiváltani, ha az átadott argumentumok a következők: bármelyik karakterlánc, bármely lista és egy nulla referencia:

nyilvános felület ExpectationsCollaborator {String methodForNulls1 (String s, l lista); void methodForNulls2 (s karakterlánc, l lista); } @Test public void testWithNulls (@Mocked ExpectationsCollaborator gúny) {new Expectations () {{mock.methodForNulls1 (anyString, null); eredmény = "null"; }}; assertEquals ("null", mock.methodForNulls1 ("blablabla", új ArrayList ())); mock.methodForNulls2 ("blablabla", null); új ellenőrzések () {{mock.methodForNulls2 (anyString, (List) withNull ()); }}; }

Vegye figyelembe a különbséget: nulla bármilyen listát jelent és withNull () jelentése: a nulla hivatkozás egy listára. Különösen így elkerülhető, hogy az értéket a deklarált paramétertípusra kell leadni (lásd: a harmadik argumentumot kellett leadni, a másodikat azonban nem).

Az egyetlen feltétel ennek használatához az, hogy legalább egy explicit argumentumillesztőt használtak az elváráshoz (vagy val vel módszer vagy an Bármi terület).

2.4. „Times” mező

Néha szeretnénk korlátozniaz invokációk száma gúnyos módszerrel várható. Ehhez a JMockit fenntartja a szavakat alkalommal, minTimes és maxTimes (mindhárom csak nem negatív egész számokat engedélyez).

nyilvános felület ExpectationsCollaborator {void methodForTimes1 (); void methodForTimes2 (); void methodForTimes3 (); } @Test public void testWithTimes (@Mocked ExpectationsCollaborator gúny) {new Expectations () {{mock.methodForTimes1 (); idők = 2; mock.methodForTimes2 (); }}; mock.methodForTimes1 (); mock.methodForTimes1 (); mock.methodForTimes2 (); mock.methodForTimes3 (); mock.methodForTimes3 (); mock.methodForTimes3 (); új ellenőrzések () {{mock.methodForTimes3 (); minTimes = 1; maxTimes = 3; }}; }

Ebben a példában meghatároztuk, hogy pontosan két invokáció (nem egy, nem három, pontosan kettő) methodForTimes1 () a vonal használatával kell elvégezni idők = 2;.

Ezután az alapértelmezett viselkedést használtuk (ha nincs megismételési kényszer minTimes = 1; használjuk), hogy meghatározzuk, hogy legalább egy meghívást fogunk tenni methodForTimes2 ().

Végül a minTimes = 1; utána maxTimes = 3; meghatároztuk, hogy egy és három invokáció fordul elő methodForTimes3 ().

Vegye figyelembe, hogy mindkettő minTimes és maxTimes megadható ugyanarra az elvárásra, mindaddig, amíg minTimes kerül előbb kijelölésre. Másrészről, alkalommal csak egyedül használható.

2.5. Egyéni argumentumillesztés

Néha az argumentumillesztés nem olyan közvetlen, mint egyszerűen megadni egy értéket vagy használni az előre meghatározott segédprogramokat (anyX vagy withX).

Ebben az esetben a JMockit Hamcrest-re támaszkodik Matcher felület. Csak meg kell határoznia egy illesztőt az adott tesztelési szcenárióhoz, és ezt a megfelelőt a withArgThat () hívás.

Lássunk egy példát egy adott osztály megfeleltetett objektumhoz való illesztésére:

nyilvános felület ExpectationsCollaborator {void methodForArgThat (o objektum); } public class Model {public String getInfo () {return "info"; }} @Test public void testCustomArgumentMatching (@Mocked ExpectationsCollaborator mock) {new Expectations () {{mock.methodForArgThat (withArgThat (new BaseMatcher () {@Override public boolean matching (Object item) {return item instanceof Model && info "). egyenlő ((((Modell) elem) .getInfo ());} @Orride public void írja le (To leírása) {}})); }}; mock.methodForArgThat (új modell ()); }

3. Visszatérő értékek

Most nézzük meg a visszatérési értékeket; ne feledje, hogy a következő megközelítések csak a következőkre vonatkoznak Elvárások mivel nem lehet visszatérési értékeket meghatározni Ellenőrzések.

3.1. Eredmény és visszatérés (…)

A JMockit használatakor három különböző módon határozhatja meg a csúfolt módszer meghívásának várható eredményét. Mindhárom közül most az első kettőről (a legegyszerűbbekről) beszélünk, amelyek biztosan lefedik a mindennapi használat 90% -át.

Ez a kettő az eredmény mező és a visszatér (Object…) módszer:

  • A ... val eredmény mezőben definiálhatja egy visszatérési értéke bármely nem érvénytelen visszatérő csúfolt módszerhez. Ez a visszatérési érték is kivételt képezhet (ezúttal nem érvénytelen és érvénytelen visszatérési módszereknél is működik).
    • Számos eredmény terepi hozzárendeléseket lehet elvégezni a visszatérés érdekében több érték egynél több metódus invokációhoz (keverheti a visszatérési értékeket és a dobandó hibákat is).
    • Ugyanezt a viselkedést fogják elérni a hozzárendeléskor is eredmény értékek listája vagy tömbje (ugyanolyan típusú, mint a gúnyolt módszer visszatérési típusa, itt nincsenek kivételek).
  • A visszatér (Object…) módszer az szintaktikus cukor ha egyszerre több értéket ad vissza.

Ez könnyebben megmutatható egy kódrészlettel:

nyilvános felület ExpectationsCollaborator {String methodReturnsString (); int methodReturnsInt (); } @Test public void testResultAndReturns (@Mocked ExpectationsCollaborator gúny) {new Expectations () {{mock.methodReturnsString (); eredmény = "foo"; eredmény = új Kivétel (); eredmény = "bár"; visszatér ("foo", "bar"); mock.methodReturnsInt (); eredmény = új int [] {1, 2, 3}; eredmény = 1; }}; assertEquals ("Ha vissza kellene térnie foo", "foo", mock.methodReturnsString ()); próbáld ki a {mock.methodReturnsString (); kudarc ("Nem szabad ide elérni"); } catch (e kivétel) {// NOOP} assertEquals ("Ha visszatér a sáv", "bár", mock.methodReturnsString ()); assertEquals ("Ha 1-nek kellene visszatérnie", 1, mock.methodReturnsInt ()); assertEquals ("Ha vissza kellene térnie 2", 2, mock.methodReturnsInt ()); assertEquals ("Ha 3-nak kellene visszatérnie", 3, mock.methodReturnsInt ()); assertEquals ("Ha vissza kellene térnie foo", "foo", mock.methodReturnsString ()); assertEquals ("Ha visszatér a sáv", "bár", mock.methodReturnsString ()); assertEquals ("Ha 1-nek kellene visszatérnie", 1, mock.methodReturnsInt ()); }

Ebben a példában meghatároztuk, hogy az első három hívásra methodReturnsString () a várható hozam (sorrendben) „Foo”, kivétel és "rúd". Ezt három különböző hozzárendeléssel értük el a eredmény terület.

Akkor tovább 14. sor, meghatároztuk, hogy a negyedik és ötödik hívásnál „Foo” és "rúd" segítségével vissza kell küldeni visszatér (Object…) módszer.

A methodReturnsInt () határoztuk tovább 13. sor hogy 1, 2 és végül 3 visszatérjen, a különböző eredményeket tartalmazó tömböt rendelve a eredmény mezőn és tovább 15. sor definiáltuk, hogy 1-et egyszerű hozzárendeléssel adjuk vissza a eredmény terület.

Mint látható, a megcsúfolt módszerek visszatérési értékeinek meghatározására többféle módszer létezik.

3.2. Delegátorok

A cikk befejezéséhez a visszatérési érték meghatározásának harmadik módszerével foglalkozunk: a Delegált felület. Ezt az interfészt komplexebb visszatérési értékek meghatározására használják a csúfolt módszerek definiálásakor.

Meglátjuk a példát a magyarázatra:

nyilvános felület ExpectationsCollaborator {int methodForDelegate (int i); } @Test public void testDelegate (@Mocked ExpectationsCollaborator gúny) {new Expectations () {{mock.methodForDelegate (anyInt); eredmény = új Delegált () {int delegált (int i) dobja a Kivételt {if (i <3) {return 5; } else {dobjon új Kivételt (); }}}; }}; assertEquals ("Vissza kell térnie 5", 5, mock.methodForDelegate (1)); próbáld ki a {mock.methodForDelegate (3); kudarc ("Nem szabad ide elérni"); } fogás (e kivétel) {}} 

A delegátor használatának módja egy új példány létrehozása és a visszatér terület. Ebben az új példában létre kell hoznia egy új metódust ugyanazokkal a paraméterekkel és visszatérési típussal, mint a gúnyolt metódus (bármilyen nevet használhatunk rá). Ebben az új módszerben használja a kívánt megvalósítást a kívánt érték visszaadásához.

A példában olyan megvalósítást hajtottunk végre, amelyben 5 vissza kell adni, ha a gúnyolt módszerhez átadott érték kisebb, mint 3 és másként kivételt vetnek (vegye figyelembe, hogy használnunk kellett idők = 2; így a második invokáció várható, mivel a visszatérési érték meghatározásával elveszítettük az alapértelmezett viselkedést).

Lehet, hogy elég sok kódnak tűnik, de bizonyos esetekben csak így lehet elérni a kívánt eredményt.

4. Következtetés

Ezzel gyakorlatilag mindent megmutattunk, amire szükségünk van ahhoz, hogy elvárásokat és igazolásokat hozzunk létre mindennapi tesztjeinkhez.

Természetesen további cikkeket fogunk közzétenni a JMockit-on, ezért figyeljen arra, hogy még többet tudjon meg.

És mint mindig, ennek az oktatóanyagnak a teljes megvalósítása megtalálható a GitHub projekten.

4.1. A sorozat cikkei

A sorozat összes cikke:

  • JMockit 101
  • Útmutató a JMockit elvárásaihoz
  • JMockit Advanced Usage