Vodič za očekivanja JMockita

1. Uvod

Ovaj je članak drugi dio u seriji JMockit. Možda ćete htjeti pročitati prvi članak jer pretpostavljamo da ste već upoznati s osnovama JMockita.

Danas ćemo ući dublje i usredotočiti se na očekivanja. Pokazat ćemo kako definirati konkretnije ili generičko podudaranje argumenata i naprednije načine definiranja vrijednosti.

2. Podudaranje vrijednosti argumenta

Sljedeći pristupi primjenjuju se na Očekivanja kao i Provjere.

2.1. "Bilo koja" polja

JMockit nudi skup korisnih polja za prilagođavanje argumenata općenitijim. Jedna od tih komunalnih usluga su bilo kojiX polja.

Oni će provjeriti je li proslijeđena bilo koja vrijednost i postoji jedna za svaki primitivni tip (i odgovarajuća klasa omota), jedna za nizove i "univerzalna" vrsta Objekt.

Pogledajmo primjer:

javno sučelje ExpectationsCollaborator {String methodForAny1 (String s, int i, Boolean b); void metodaForAny2 (Long l, List lst); } @Test test javne praznine (@Mocked ExpecationsCollaborator mock) baca Izuzetak {nova očekivanja () {{mock.methodForAny1 (anyString, anyInt, anyBoolean); rezultat = "bilo koji"; }}; Assert.assertEquals ("bilo koji", mock.methodForAny1 ("barfooxyz", 0, Boolean.FALSE)); mock.methodForAny2 (2L, novi ArrayList ()); nove FullVerifications () {{mock.methodForAny2 (anyLong, (List) any); }}; }

Morate uzeti u obzir da kada koristite bilo koji polje, trebate ga prebaciti na očekivani tip. Potpuni popis polja nalazi se u dokumentaciji.

2.2. "Sa" metodama

JMockit također nudi nekoliko metoda koje pomažu u generičkom podudaranju argumenata. To su saX metode.

Oni omogućuju malo naprednije podudaranje od bilo kojiX polja. Ovdje možemo vidjeti primjer u kojem ćemo definirati očekivanje za metodu koja će se pokretati nizom koji sadrži foo, cijeli broj koji nije jednak 1, ne-null Booleova i bilo koji primjer Popis razred:

javno sučelje ExpectationsCollaborator {String methodForWith1 (String s, int i); void metodaForWith2 (logička b, popis l); } @Test public void testForWith (@Mocked ExpecationsCollaborator mock) baca izuzetak {nova očekivanja () {{mock.methodForWith1 (withSubstring ("foo"), withNotEqual (1)); rezultat = "sa"; }}; assertEquals ("with", mock.methodForWith1 ("barfooxyz", 2)); mock.methodForWith2 (Boolean.TRUE, novi ArrayList ()); nove provjere () {{mock.methodForWith2 (withNotNull (), withInstanceOf (List.class)); }}; }

Možete vidjeti cjelovit popis saX metode u JMockitovoj dokumentaciji.

Uzmi u obzir da je posebna s (delegat) i withArgThat (Matcher) bit će obrađeni u vlastitom pododjeljku.

2.3. Null nije null

Nešto što je dobro razumjeti prije nego kasnije je to null se ne koristi za definiranje argumenta za koji null je proslijeđen rugalici.

Zapravo, null koristi se kao sintaktički šećer definirati da će bilo koji objekt biti proslijeđen (tako da se može koristiti samo za parametre referentnog tipa). Da biste posebno provjerili prima li zadani parametar null referenca, withNull () može se koristiti podudaranje.

Za sljedeći primjer definirat ćemo ponašanje lažnog ponašanja koje bi se trebalo aktivirati kada su proslijeđeni argumenti: bilo koji niz, bilo koji Popis i null referenca:

javno sučelje ExpecationsCollaborator {String methodForNulls1 (String s, List l); void metodaForNulls2 (Niz s, Popis l); } @Test public void testWithNulls (@Mocked ExpecationsCollaborator mock) {new Expe ожидаvanja () {{mock.methodForNulls1 (anyString, null); rezultat = "null"; }}; assertEquals ("null", mock.methodForNulls1 ("blablabla", novi ArrayList ())); mock.methodForNulls2 ("blablabla", null); nove provjere () {{mock.methodForNulls2 (anyString, (List) withNull ()); }}; }

Primijetite razliku: null znači bilo koji popis i withNull () znači a null referenca na popis. To posebno izbjegava potrebu za emitiranjem vrijednosti na deklarirani tip parametra (pogledajte da je treći argument trebao biti izbačen, ali ne i drugi).

Jedini uvjet da se to može koristiti je da je za očekivanje korišten barem jedan eksplicitni podudarnik argumenata (bilo s metoda ili an bilo koji polje).

2.4. Polje "Times"

Ponekad to želimo nagnatibroj zaziva očekuje se za izrugivanu metodu. Zbog toga JMockit ima rezervirane riječi puta, min VRIJEME i maxTimes (sve tri dopuštaju samo negativne cijele brojeve).

javno sučelje ExpecationsCollaborator {void methodForTimes1 (); void metodaForTimes2 (); void metodaForTimes3 (); } @Test public void testWithTimes (@Mocked ExpecationsCollaborator mock) {nova očekivanja () {{mock.methodForTimes1 (); puta = 2; mock.methodForTimes2 (); }}; mock.methodForTimes1 (); mock.methodForTimes1 (); mock.methodForTimes2 (); mock.methodForTimes3 (); mock.methodForTimes3 (); mock.methodForTimes3 (); nove provjere () {{mock.methodForTimes3 (); minTimes = 1; maxTimes = 3; }}; }

U ovom smo primjeru definirali da točno dva poziva (ne jedan, ne tri, točno dva) od methodForTimes1 () treba obaviti pomoću crte puta = 2;.

Tada smo upotrijebili zadano ponašanje (ako nije dato ograničenje ponavljanja minTimes = 1; koristi se) za definiranje da će se izvršiti barem jedan poziv methodForTimes2 ().

Na kraju, koristeći minTimes = 1; nakon čega slijedi maxTimes = 3; definirali smo da će se dogoditi između jednog i tri poziva methodForTimes3 ().

Uzmi u obzir da oboje min VRIJEME i maxTimes može se navesti za isto očekivanje, sve dok min VRIJEME je dodijeljen prvi. S druge strane, puta može se koristiti samo samostalno.

2.5. Podudaranje prilagođenih argumenata

Ponekad podudaranje argumenata nije tako izravno kao jednostavno određivanje vrijednosti ili korištenje nekih od unaprijed definiranih uslužnih programa (bilo kojiX ili saX).

U tim se slučajevima JMockit oslanja na Hamcrest-ove Podudaranje sučelje. Samo trebate definirati podudaranje za određeni scenarij testiranja i upotrijebiti to podudaranje s withArgThat () poziv.

Pogledajmo primjer za podudaranje određene klase s prosljeđenim objektom:

javno sučelje ExpecationsCollaborator {void methodForArgThat (Objekt o); } model javne klase {javni niz getInfo () {return "info"; }} @Test public void testCustomArgumentMatching (@Mocked ExpecationsCollaborator mock) {nova očekivanja () {{mock.methodForArgThat (withArgThat (new BaseMatcher () {@ Nadjačaj javne logičke podudaranja (objektna stavka) {return item instanceof Model && "info". jednako (((Model) stavka) .getInfo ());} @Override public void descriTo (Opis opisa) {}})); }}; mock.methodForArgThat (novi model ()); }

3. Vrijednosti koje se vraćaju

Pogledajmo sada povratne vrijednosti; imajte na umu da se sljedeći pristupi odnose samo na Očekivanja jer se ne mogu definirati povratne vrijednosti za Provjere.

3.1. Rezultat i povrat (...)

Kada koristite JMockit, imate tri različita načina definiranja očekivanog rezultata pozivanja izrugivane metode. Od sve tri, sada ćemo razgovarati o prva dva (najjednostavnija) koja će zasigurno pokriti 90% slučajeva svakodnevne uporabe.

Ovo dvoje su proizlaziti polje i vraća (objekt ...) metoda:

  • Uz proizlaziti polje, možete definirati jedan povratna vrijednost za bilo koju nevažeću povratnu ismijanu metodu Ova povratna vrijednost također može biti iznimka koju treba izbaciti (ovaj put radi i za nevažeće i za void metode vraćanja).
    • Nekoliko proizlaziti terenska dodjeljivanja mogu se izvršiti kako bi se vratio više od jedne vrijednosti za više od jednog poziva metode (možete kombinirati i povratne vrijednosti i pogreške koje treba izbaciti).
    • Isto ponašanje postići će se i pri dodjeli proizlaziti popis ili niz vrijednosti (iste vrste od one vrste povratka rugane metode, ovdje NEMA izuzetaka).
  • The vraća (objekt ...) metoda je sintaktički šećer za vraćanje nekoliko vrijednosti istovremeno.

To je lakše prikazati isječkom koda:

javno sučelje ExpecationsCollaborator {String methodReturnsString (); int methodReturnsInt (); } @Test public void testResultAndReturns (@Mocked ExpecationsCollaborator mock) {nova očekivanja () {{mock.methodReturnsString (); rezultat = "foo"; rezultat = nova iznimka (); rezultat = "traka"; vraća se ("foo", "bar"); mock.methodReturnsInt (); rezultat = novi int [] {1, 2, 3}; rezultat = 1; }}; assertEquals ("Treba vratiti foo", "foo", mock.methodReturnsString ()); isprobajte {mock.methodReturnsString (); fail ("Ne bih trebao doći ovdje"); } catch (Exception e) {// NOOP} assertEquals ("Should return bar", "bar", mock.methodReturnsString ()); assertEquals ("Treba vratiti 1", 1, mock.methodReturnsInt ()); assertEquals ("Treba vratiti 2", 2, mock.methodReturnsInt ()); assertEquals ("Treba vratiti 3", 3, mock.methodReturnsInt ()); assertEquals ("Treba vratiti foo", "foo", mock.methodReturnsString ()); assertEquals ("Treba vratiti bar", "bar", mock.methodReturnsString ()); assertEquals ("Treba vratiti 1", 1, mock.methodReturnsInt ()); }

U ovom smo primjeru to definirali za prva tri poziva na methodReturnsString () očekivani prinosi su (u redu) "Foo", iznimka i "bar". To smo postigli koristeći tri različita dodjeljivanja proizlaziti polje.

Zatim dalje redak 14, definirali smo da za četvrti i peti poziv, "Foo" i "bar" treba vratiti pomoću vraća (objekt ...) metoda.

Za methodReturnsInt () definirali smo na red 13 za vraćanje 1, 2 i na kraju 3 dodjeljivanjem polja s različitim rezultatima proizlaziti polje i dalje redak 15 definirali smo da vratimo 1 jednostavnim dodjeljivanjem proizlaziti polje.

Kao što vidite, postoji nekoliko načina definiranja povratnih vrijednosti za izrugivane metode.

3.2. Delegatori

Za kraj članka obradit ćemo treći način definiranja povratne vrijednosti: Delegat sučelje. Ovo sučelje koristi se za definiranje složenijih povratnih vrijednosti prilikom definiranja ismijanih metoda.

Vidjet ćemo primjer za jednostavno objašnjenje:

javno sučelje ExpecationsCollaborator {int methodForDelegate (int i); } @Test public void testDelegate (@Mocked ExpecationsCollaborator mock) {nova očekivanja () {{mock.methodForDelegate (anyInt); rezultat = novi Delegat () {int delegat (int i) baca iznimku {if (i <3) {return 5; } else {baciti novi Exception (); }}}; }}; assertEquals ("Treba vratiti 5", 5, mock.methodForDelegate (1)); isprobajte {mock.methodForDelegate (3); fail ("Ne bih trebao doći ovdje"); } ulov (izuzetak e) {}} 

Način korištenja delegatora je stvaranje nove instance za njega i dodjeljivanje a vraća se polje. U ovoj novoj instanci trebali biste stvoriti novu metodu s istim parametrima i tipom povratka od podsmijevane metode (za nju možete koristiti bilo koji naziv). Unutar ove nove metode koristite bilo koju implementaciju koju želite kako biste vratili željenu vrijednost.

U primjeru smo izvršili implementaciju u kojoj 5 treba vratiti kada je vrijednost proslijeđena ismijanoj metodi manja od 3 a izuzetak je izbačen u suprotnom (imajte na umu da smo morali koristiti puta = 2; tako da se očekuje drugi poziv jer smo izgubili zadano ponašanje definiranjem povratne vrijednosti).

Možda se čini kao prilično puno koda, ali u nekim će slučajevima to biti jedini način da postignemo željeni rezultat.

4. Zaključak

Ovim smo praktički pokazali sve što nam je potrebno za stvaranje očekivanja i provjera za naše svakodnevne testove.

Naravno, objavit ćemo još članaka o JMockitu, pa budite uz nas da biste saznali još više.

Kao i uvijek, potpunu provedbu ovog vodiča možete pronaći na projektu GitHub.

4.1. Članci u seriji

Svi članci serije:

  • JMockit 101
  • Vodič za JMockit očekivanja
  • Napredno korištenje JMockita

$config[zx-auto] not found$config[zx-overlay] not found