Sprievodca očakávaním JMockit

1. Úvod

Tento článok je druhým pokračovaním v sérii JMockit. Možno si budete chcieť prečítať prvý článok, pretože predpokladáme, že základné princípy JMockit už poznáte.

Dnes pôjdeme hlbšie a zameriame sa na očakávania. Ukážeme si, ako definovať konkrétnejšie alebo všeobecnejšie zhody argumentov a pokročilejšie spôsoby definovania hodnôt.

2. Zhoda hodnôt argumentov

Nasledujúce prístupy sa vzťahujú na: Očakávania ako aj Overenia.

2.1. „Ľubovoľné“ polia

JMockit ponúka množinu úžitkových polí na generické spárovanie argumentov. Jedným z týchto nástrojov sú anyX polia.

Tieto skontrolujú, či bola odovzdaná akákoľvek hodnota a že existuje jedna pre každý primitívny typ (a zodpovedajúca trieda obálky), jedna pre reťazce a „univerzálna“ typu Objekt.

Pozrime sa na príklad:

verejné rozhranie ExpectationsCollaborator {String methodForAny1 (String s, int i, Boolean b); void methodForAny2 (Long l, List lst); } @Test public void test (@Mocked ExpectationsCollaborator mock) hodí výnimku {new Expectations () {{mock.methodForAny1 (anyString, anyInt, anyBoolean); výsledok = "akýkoľvek"; }}; Assert.assertEquals ("any", mock.methodForAny1 ("barfooxyz", 0, Boolean.FALSE)); mock.methodForAny2 (2L, nový ArrayList ()); new FullVerifications () {{mock.methodForAny2 (anyLong, (List) any); }}; }

Musíte brať do úvahy, že pri používaní akýkoľvek pole, musíte ho obsadiť do očakávaného typu. Kompletný zoznam polí je uvedený v dokumentácii.

2.2. „S“ metódami

JMockit tiež poskytuje niekoľko metód na pomoc so zhodou všeobecných argumentov. To sú tí withX metódy.

Umožňujú trochu pokročilejšie priraďovanie ako anyX polia. Vidíme tu príklad, v ktorom definujeme očakávanie pre metódu, ktorá sa spustí s reťazcom obsahujúcim foo, celé číslo nie rovné 1, nenulové Boolovský a akýkoľvek prípad Zoznam trieda:

verejné rozhranie ExpectationsCollaborator {String methodForWith1 (String s, int i); void methodForWith2 (Boolean b, zoznam l); } @Test public void testForWith (@Mocked ExpectationsCollaborator mock) hodí Exception {new Expectations () {{mock.methodForWith1 (withSubstring ("foo"), withNotEqual (1)); výsledok = "s"; }}; assertEquals ("with", mock.methodForWith1 ("barfooxyz", 2)); mock.methodForWith2 (Boolean.TRUE, nový ArrayList ()); new Verifications () {{mock.methodForWith2 (withNotNull (), withInstanceOf (List.class)); }}; }

Môžete vidieť kompletný zoznam withX metódy v dokumentácii JMockit.

Berte do úvahy, že špeciálne s (delegátom) a withArgThat (Matcher) sa bude zaoberať ich vlastná pododdiel.

2.3. Null nie je Null

Je niečo, čo je dobré pochopiť skôr ako neskôr nulový sa nepoužíva na definovanie argumentu, pre ktorý nulový bol odovzdaný falošnej osobe.

Vlastne, nulový sa používa ako syntaktický cukor definovať, že bude odovzdaný akýkoľvek objekt (takže ho možno použiť iba pre parametre referenčného typu). Konkrétne overiť, či daný parameter prijíma nulový odkaz, withNull () môže byť použitý matcher.

V nasledujúcom príklade definujeme správanie falošného, ​​ktoré by sa malo spustiť, keď sú odovzdané argumenty: akýkoľvek reťazec, akýkoľvek zoznam a nulový referencia:

verejné rozhranie ExpectationsCollaborator {String methodForNulls1 (String s, List l); void methodForNulls2 (Reťazec s, Zoznam l); } @Test public void testWithNulls (@Mocked ExpectationsCollaborator mock) {new Expectations () {{mock.methodForNulls1 (anyString, null); result = "null"; }}; assertEquals ("null", mock.methodForNulls1 ("blablabla", nový ArrayList ())); mock.methodForNulls2 ("blablabla", null); new Verifications () {{mock.methodForNulls2 (anyString, (List) withNull ()); }}; }

Všimnite si rozdiel: nulový znamená akýkoľvek zoznam a withNull () znamená a nulový odkaz na zoznam. Tým sa predovšetkým zabráni nutnosti prenášať hodnotu na deklarovaný typ parametra (pozri, že musel byť použitý tretí argument, ale nie druhý).

Jedinou podmienkou, ktorá to umožní, je to, že na očakávanie bol použitý aspoň jeden explicitný porovnávač argumentov (buď a s metóda alebo akýkoľvek lúka).

2.4. Pole „Times“

Niekedy chceme obmedziťpočet vyvolaných očakáva sa pre vysmievanú metódu. Na tento účel má JMockit vyhradené slová krát, minTimes a maxTimes (všetky tri umožňujú iba nezáporné celé čísla).

verejné rozhranie ExpectationsCollaborator {void methodForTimes1 (); void methodForTimes2 (); void methodForTimes3 (); } @Test public void testWithTimes (@Mocked ExpectationsCollaborator mock) {new Expectations () {{mock.methodForTimes1 (); krát = 2; mock.methodForTimes2 (); }}; mock.methodForTimes1 (); mock.methodForTimes1 (); mock.methodForTimes2 (); mock.methodForTimes3 (); mock.methodForTimes3 (); mock.methodForTimes3 (); new Verifications () {{mock.methodForTimes3 (); minTimes = 1; maxTimes = 3; }}; }

V tomto príklade sme definovali presne dve vyvolania (nie jedno, nie tri, presne dve) methodForTimes1 () by sa malo vykonať pomocou linky krát = 2;.

Potom sme použili predvolené správanie (ak nie je dané obmedzenie opakovania minTimes = 1; sa používa) na definovanie toho, že sa uskutoční najmenej jedno vyvolanie služby methodForTimes2 ().

Nakoniec pomocou minTimes = 1; nasledovaný maxTimes = 3; definovali sme, že by došlo k jednému až troma vyvolaniu methodForTimes3 ().

Berte do úvahy, že oboje minTimes a maxTimes možno určiť pre rovnaké očakávanie, pokiaľ minTimes je priradený ako prvý. Na druhej strane, krát je možné použiť iba samostatne.

2.5. Zhoda vlastných argumentov

Zhoda argumentov niekedy nie je taká priama, ako jednoduché zadanie hodnoty alebo použitie niektorého z preddefinovaných nástrojov (anyX alebo withX).

V týchto prípadoch sa JMockit spolieha na Hamcrestov Matcher rozhranie. Musíte len definovať porovnávač pre konkrétny testovací scenár a použiť tento porovnávač s a withArgThat () hovor.

Pozrime sa na príklad zhody konkrétnej triedy s odovzdaným objektom:

verejné rozhranie ExpectationsCollaborator {void methodForArgThat (objekt o); } verejná trieda Model {public String getInfo () {return "info"; }} @Test public void testCustomArgumentMatching (@Mocked ExpectationsCollaborator mock) {new Expectations () {{mock.methodForArgThat (withArgThat (new BaseMatcher () {@Override public boolean matchs (Object item) {return item instanceof Model && "info". equals ((((Model) item) .getInfo ());} @Override public void describeTo (Description description) {}})); }}; mock.methodForArgThat (nový model ()); }

3. Vrátenie hodnôt

Pozrime sa teraz na návratové hodnoty; majte na pamäti, že nasledujúce prístupy sa vzťahujú iba na Očakávania pretože nie je možné definovať návratové hodnoty pre Overenia.

3.1. Výsledok a vrátenie tovaru (...)

Keď používate JMockit, máte tri rôzne spôsoby definovania očakávaného výsledku vyvolania vysmievanej metódy. Zo všetkých troch si teraz povieme niečo o prvých dvoch (najjednoduchších), ktoré určite pokryjú 90% prípadov každodenného použitia.

Títo dvaja sú výsledok pole a vráti (objekt…) metóda:

  • Vďaka výsledok môžete definovať jeden návratová hodnota pre každú nepoškodenú vracajúcu sa metódu. Táto návratová hodnota môže byť tiež výnimkou, ktorá sa má vyhodiť (tentoraz pracuje pre metódy vracania aj neplatnosti).
    • Niekoľko výsledok priraďovanie polí je možné vykonať za účelom návratu viac ako jedna hodnota pre viac ako jedno vyvolanie metódy (môžete kombinovať vrátené hodnoty aj chyby, ktoré sa majú vyhodiť).
    • Rovnaké správanie sa dosiahne pri priraďovaní k položke výsledok zoznam alebo pole hodnôt (rovnakého typu ako návratový typ vysmievanej metódy, tu NEŽIADNE výnimky).
  • The vráti (objekt…) metóda je syntaktický cukor pre vrátenie viacerých hodnôt súčasne.

Toto sa ľahšie ukáže pomocou útržku kódu:

verejné rozhranie ExpectationsCollaborator {String methodReturnsString (); int methodReturnsInt (); } @Test public void testResultAndReturns (@Mocked ExpectationsCollaborator mock) {new Expectations () {{mock.methodReturnsString (); výsledok = "foo"; výsledok = nová výnimka (); výsledok = "bar"; returns ("foo", "bar"); mock.methodReturnsInt (); výsledok = nový int [] {1, 2, 3}; výsledok = 1; }}; assertEquals ("Malo by sa vrátiť foo", "foo", mock.methodReturnsString ()); try {mock.methodReturnsString (); zlyhať („Nemalo by sa sem dostať“); } catch (Výnimka e) {// NOOP} assertEquals ("Mal by vrátiť bar", "bar", mock.methodReturnsString ()); assertEquals ("Malo by vrátiť 1", 1, mock.methodReturnsInt ()); assertEquals ("Malo by sa vrátiť 2", 2, mock.methodReturnsInt ()); assertEquals ("Malo by sa vrátiť 3", 3, mock.methodReturnsInt ()); assertEquals ("Malo by sa vrátiť foo", "foo", mock.methodReturnsString ()); assertEquals ("Mal by vrátiť bar", "bar", mock.methodReturnsString ()); assertEquals ("Malo by vrátiť 1", 1, mock.methodReturnsInt ()); }

V tomto príklade sme definovali, že pre prvé tri hovory na methodReturnsString () očakávané výnosy sú (v poradí) „Foo“, výnimka a „Bar“. Dosiahli sme to pomocou troch rôznych priradení k výsledok lúka.

Potom ďalej riadok 14, definovali sme, že pre štvrtý a piaty hovor, „Foo“ a „Bar“ by sa mali vrátiť pomocou vráti (objekt…) metóda.

Pre methodReturnsInt () definovali sme dňa riadok 13 vrátiť 1, 2 a nakoniec 3 priradením poľa s rôznymi výsledkami k výsledok pole a ďalej riadok 15 definovali sme návrat 1 jednoduchým priradením k výsledok lúka.

Ako vidíte, existuje niekoľko spôsobov definovania návratových hodnôt pre vysmievané metódy.

3.2. Delegáti

Na záver článku sa budeme zaoberať tretím spôsobom definovania návratovej hodnoty: Delegát rozhranie. Toto rozhranie sa používa na definovanie zložitejších návratových hodnôt pri definovaní vysmievaných metód.

Uvidíme príklad na jednoduché vysvetlenie:

verejné rozhranie ExpectationsCollaborator {int methodForDelegate (int i); } @Test public void testDelegate (@Mocked ExpectationsCollaborator mock) {new Expectations () {{mock.methodForDelegate (anyInt); result = new Delegate () {int delegate (int i) throws Exception {if (i <3) {return 5; } else {hodit novu vynimku (); }}}; }}; assertEquals ("Malo by vrátiť 5", 5, mock.methodForDelegate (1)); try {mock.methodForDelegate (3); zlyhať („Nemalo by sa sem dostať“); } úlovok (Výnimka e) {}} 

Spôsob, ako použiť delegátora, je vytvoriť pre neho novú inštanciu a priradiť ju k a vracia lúka. V tejto novej inštancii by ste mali vytvoriť novú metódu s rovnakými parametrami a návratovým typom, ako je vysmievaná metóda (môžete pre ňu použiť ľubovoľný názov). V rámci tejto novej metódy použite ľubovoľnú implementáciu, aby ste vrátili požadovanú hodnotu.

V príklade sme vykonali implementáciu, v ktorej 5 by sa mali vrátiť, keď je hodnota odovzdaná vysmievanej metóde menšia ako 3 a inak sa hodí výnimka (všimnite si, že sme to museli použiť krát = 2; takže druhé vyvolanie sa očakáva, pretože sme stratili predvolené správanie definovaním návratovej hodnoty).

Môže sa to zdať ako pomerne veľa kódu, ale v niektorých prípadoch to bude jediný spôsob, ako dosiahnuť požadovaný výsledok.

4. Záver

Týmto sme prakticky ukázali všetko, čo potrebujeme na vytvorenie očakávaní a overení pre naše každodenné testy.

Samozrejme uverejníme viac článkov o JMockit, takže zostaňte naladení, aby ste sa dozvedeli ešte viac.

A ako vždy, úplnú implementáciu tohto tutoriálu nájdete v projekte GitHub.

4.1. Články v seriáli

Všetky články zo série:

  • JMockit 101
  • Sprievodca očakávaním JMockit
  • Pokročilé použitie JMockit

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