spock mocking stubbing
Posmievanie, pichanie a špehovanie pomocou Spocka:
Parametrizované testovanie v Spock Framework bolo v tomto podrobne vysvetlené Séria výcvikových tutoriálov na Spocku .
Mocking a Stubbing sú jedným z najdôležitejších stavebných kameňov rozsiahlych testov jednotiek. Podpora zosmiešňovania a podrezávania je ako čerešnička na torte pre rámec.
Pre existujúce rámce ako JUnit, JBehave atď. Podpora pre falošné a pahýľky nevychádza z krabice, preto vyžaduje, aby vývojár použil knižnice tretích strán, ako sú Mockito, PowerMock, EasyMock atď., Aby ich mohol použiť v jednotkové testy.
Aby ste pochopili falošné pokusy a pahýly a ich prípady použitia, môžete sa pozrieť na našu sériu Výukový program pre Mockito .
V tomto tutoriále sa dozvieme viac o vstavaných funkciách Mocking and Stubbing integrovaných do samotnej knižnice Spock, ktoré by zase umožnili používať ľahšiu Groovy syntax a tým znižovali potrebu pridávať / pridávať akékoľvek ďalšie 3rdstranícke knižnice.
Do svojich testov môžete kedykoľvek zahrnúť ďalšie rámce Mocking, pretože aj všetok platný kód Java je platným kódom Groovy.
Čo sa dozviete:
- Testovaná aplikácia
- Mocking in Spock
- Bodnutie v Spockovi
- Špehuje v Spockovi
- Záver
- Zdrojový kód aplikácie
- Odporúčané čítanie
Testovaná aplikácia
Poďme si najskôr definovať ukážkovú Java aplikáciu, ktorú budeme testovať pomocou simulov a stubov v rámci Spocku.
Budeme pracovať na aplikácii StudentGradeCalculator, ktorá vezme celkové skóre z abstrahovanej databázy pre dané ID študenta a má jednoduchú logiku priradenia známok v závislosti od hodnoty celkového skóre. Použijeme databázové rozhranie, ktoré má niekoľko metód na získanie a aktualizáciu skóre a známok študentov.
Kód aplikácie bude k dispozícii v poslednej časti tohto tutoriálu.
Mocking in Spock
Videonávod
prevádzať youtube video na mp4 online zadarmo
V tejto časti uvidíme, ako vytvoriť inštancie a inicializovať Mocks v rámci Spocka a ako overiť interakcie na falošnom základe, t. J. Overenie hovorov na falošné pokusy sa uskutočnilo podľa očakávaní testovanej metódy.
S Mocks nemusíte robiť veľa nastavení, ale môžete overiť interakcie, ktoré sa stali s falošnými objektmi dodanými do testovanej aplikácie.
S posmeškami môžete robiť napríklad tieto veci:
- S akými argumentmi sa vysmievali?
- Aký bol celkový počet vyvolávaní atď.?
- Zisťovanie poradia falošných správ.
Pozrime sa na jednoduchý príklad StudentGradeCalculator, kde dodáme zosmiešnený objekt implementácie databázy a overíme interakcie s Mockom. Pokúsime sa pochopiť posmešné funkcie na jednoduchých príkladoch.
Upozorňujeme, že všetky validácie interakcií by sa mali podľa konvencie uskutočňovať v bloku „then“.
Nižšie je uvedený kód testovanej metódy (ktoré sa budú volať v „ kedy: ”Blok)
public String calculateStudentGrade(String studentId) { String grade; // check if grade is already there in database grade = studentDatabase.getStudentGrade(studentId); if(grade!=null && !grade.isEmpty()) { return grade; } List scoreList = studentDatabase.getStudentScores(studentId); Float totalScore = 0F; if(scoreList !=null) totalScore = scoreList.stream().reduce(0F,(a,b)->a+b); if(totalScore > 90) { grade = 'A'; } else if (totalScore > 80) { grade = 'B'; } else { grade = 'C'; } // update the calculated grade in database studentDatabase.updateStudentGrade(studentId, grade); return grade; }
# 1) Validácia interakcií pomocou presných argumentov: Poďme si najskôr overiť interakcie s presne očakávanými argumentmi. Tu budeme očakávať, že sa vysmievané metódy budú volať s presnými argumentmi (podľa toku vykonávania metódy).
Tu ' studentDatabase „Je vzorom databázového rozhrania, pre ktoré overujeme interakcie.
def 'illustrate mocks for interaction verification with arguments'() { when: studentReportGenerator.calculateStudentGrade('123'); then: 1*studentDatabase.updateStudentGrade('123','C') 1*studentDatabase.getStudentGrade('123') }
Ako je uvedené vyššie, overujeme pomocou presných argumentov, takže sa muselo volať s vysmievanou implementáciou. Akékoľvek zmeny týchto argumentov spôsobia zlyhanie testu a chybový protokol zobrazuje vhodný dôvod.
Skúsme zmeniť známku v updateStudentGrade ”Až“ A ”namiesto skutočne nazývaného“ C ”a uvidíte, akú chybu dostaneme pri vykonaní testu.
Too few invocations for: 1*studentDatabase.updateStudentGrade('123','A') (0 invocations) Unmatched invocations (ordered by similarity): 1 * studentDatabase.updateStudentGrade('123', 'C') 1 * studentDatabase.getStudentScores('123')
Ukáže chybu ako „Príliš málo vyvolávaní“, pretože nedokáže nájsť Mock vyvolanie s dodanými argumentmi.
otázky týkajúce sa rozhovoru pre kódovanie Java pre skúsených
#dva) Teraz sa pozrime, ako overiť Mockove interakcie bez zadania skutočných hodnôt argumentov, t. J. To, čo nás zaujíma, je však len vedieť, že v metóde bol vyvolaný falošný pokus, ale nie aké argumenty.
Tieto typy požiadaviek sú najbežnejšie pri písaní testov jednotiek pre skutočný produkčný kód, pretože nie je vždy ľahké identifikovať skutočné argumenty, ktoré v podstate závisia od základnej obchodnej logiky testovanej aplikácie.
Syntax je jednoduchá, stačí použiť podčiarkovník „_“ pre argument, kde skutočná hodnota nie je známa.
Napríklad, na kontrolu akejkoľvek hodnoty reťazca stačí spomenúť „_ Ako reťazec ”Namiesto argumentu v teste a mal by vyhovovať akejkoľvek hodnote reťazca (podobne aj pre iné primitívne aj vlastné dátové typy).
Poďme to pochopiť na príklade
def 'illustrate mocks for interaction verification with generic matchers'() { when: studentReportGenerator.calculateStudentGrade('123'); then: 1*studentDatabase.updateStudentGrade(_ as String, _ as String) 1*studentDatabase.getStudentGrade('123') }
Tu je dôležité poznamenať, že vždy môžete kombinovať, ktoré argumenty sú známe a čo nie sú známe. Napríklad v príklade nižšie overujeme interakciu jedného simulovaného so skutočnými argumentmi a druhého s voľnými porovnávačmi.
# 3) Na záver sa pozrime na scenár, v ktorom môžeme zistiť poradie falošnej invokácie, t. J. Aké poradie sa falošné čísla volali pri vykonaní testu.
Niekedy je nevyhnutné overiť tok udalostí, keď je do testovanej aplikácie zapojených viac spolupracovníkov / falošných osôb, a je užitočné pochopiť a overiť, že metódy sa volali vo vopred určenom poradí.
def 'illustrate mocks for validating order'() { when: studentReportGenerator.calculateStudentGrade('123'); then: 1*studentDatabase.getStudentGrade('123') then: 1*studentDatabase.updateStudentGrade(_ as String, _ as String) }
To sa dá dosiahnuť jednoduchým použitím viacerých blokov „then:“ v poradí podľa očakávaní Mock sekvencie. Ak uvedená postupnosť nesplnila skutočné poradie vyvolania, je vyvolaná chyba s podrobnosťou „Chybná objednávka vyvolania“.
Napríklad, ak zmením poradie vyššie uvedeného potom príkazov, vykonanie testu spôsobí chybu, ako je uvedené nižšie.
Wrong invocation order for: 1*studentDatabase.updateStudentGrade(_ as String, _ as String) (1 invocation) Last invocation: studentDatabase.updateStudentGrade('123', 'C')
Bodnutie v Spockovi
Videonávod
Preskúmali sme všetko o mockingu, teraz sa pozrime, ako definovať pahýly na vysmievaných objektoch. Stubbing nie je nič iné ako nastavenie preddefinovaných alebo konzervovaných odpovedí na Mock volanie, aby sa otestovali rôzne toky / scenáre testovanej aplikácie.
Predstavte si to ako programovanie falošného programu, ktorý vráti vopred definovanú hodnotu, keď sa volá. Budeme pokračovať v rovnakej aplikácii StudentGradeCalculator a ukončíme volania databázového rozhrania, aby sme otestovali rôzne scenáre.
Pahýľ je ako maketa, ktorá svojím spôsobom napodobňuje správanie skutočného objektu. Môžete to jednoducho nazvať ako naprogramovaný Mock.
Stubbing Syntax
Syntax pre stubbing je 2 operátory pravého posunu - teda „ >> „
Ak chcete nastaviť blokovanie hovoru pri ľubovoľnom hovore, môžete ho definovať takto:
StubbedObject.StubbedMethod(//argumentList) >> “Stubbed Response”
Poďme si teraz predstaviť príklady rôznych scenárov útlmu.
# 1) Stubbing so skutočnými parametrami: Ak sú argumenty známe vopred alebo ak chcete nastaviť pahýl iba vtedy, keď je vyvolanie so zadanými argumentmi, je možné použiť tento spôsob určenia pahýlov.
def 'illustrate stubs with exact matchers'() { given: studentDatabase.getStudentScores('123') >> (20F, 30F, 50F) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'A' }
Tu vidíte, že stub bol nastavený s presným argumentom, tj. StudentId v tomto prípade ako „123“ (pre akúkoľvek inú hodnotu nebude stub vyvolaný a bude vrátená predvolená odpoveď).
# 2) Stubbing so zhovievavými matchermi: Ak argumenty nie sú známe (alebo nie sú dôležité), môžeme ich spomenúť voľne, ako sme to urobili pre falošné správy, a ich syntax zostáva rovnaká, t. J. Podčiarkovník „_“.
def 'illustrate stubs with loose matchers'() { given: studentDatabase.getStudentScores(_ as String) >> (20F, 30F, 10F) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'C' }
# 3) Pozrime sa na ďalší rýchly príklad, keď sme nastavili pahýl, ktorý by spôsobil výnimku.
Tieto scenáre sú veľmi užitočné na overenie logiky spracovania chýb testovanej aplikácie (ako v skutočnom svete nie je generovanie všetkých výnimiek skutočne možné, ale je možné nastaviť jednoduchý stub, ktorý vráti ľubovoľnú výnimku, a potom ju uplatniť v vtedajší blok).
rozhovor s technikom v sieti 250 a viac otázok a odpovedí vysvetlených v pdf
def 'illustrate stubs with exceptions thrown'() { given: studentDatabase.getStudentScores(_ as String) >> {throw new RuntimeException()} when: studentReportGenerator.calculateStudentGrade('123') then: thrown(RuntimeException.class) }
Špehuje v Spockovi
Špióni sú založené na skutočných objektoch tj. potrebujú implementáciu rozhrania a nie samotné abstraktné rozhranie. Špióni sú mocní a môžu vám umožniť získať skutočné metódy volané pre testovanú aplikáciu a overiť, aké argumenty tieto metódy požadovali.
Spies tiež umožňujú definovať čiastočné posmešky na inštancie špehovaného objektu. tj. predpokladajme, že chcete definovať správanie niektorých metód na objekte, potom môžete a dovoľte, aby sa zvyšok volal ako skutočné volanie metód.
Sú zvyčajne užitočné v situácii, keď môžu existovať niektoré metódy rozhrania, ktoré nie sú implementované, a existuje niekoľko ďalších, ktoré sú plne funkčné. Preto sa ako vývojár môžete rozhodnúť, že zavrhnete neimplementované a zavoláte skutočné implementácie funkčných metód.
Je potrebné poznamenať, že pre špionážne objekty, pokiaľ nie sú definované pahýle, bude predvoleným správaním volanie skutočnej implementácie. To znamená, že špióni by sa nemali často nazývať a pokrytie všetkých scenárov je možné dosiahnuť pomocou falošných správ a pahýlov a ich kombinácie.
Pozrime sa na niekoľko príkladov použitia Spies v rámci Spock s rovnakým príkladom StudentGradeCalculator (Vytvorili sme skutočnú implementáciu StudentDatabase čo je implementácia v pamäti pomocou HashMap na ilustráciu volania skutočných metód a vrátenia údajov. Kód bude k dispozícii v poslednej časti tutoriálu):
# 1) Špionáž pomocou kombinácie stub a skutočných volaní metód
def 'illustrate spies'() { given: StudentDatabase spiedStudentDatabase = Spy(StudentDatabase.class) def studentReportGenerator = new StudentReportGenerator(spiedStudentDatabase) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'A' 1*spiedStudentDatabase.getStudentGrade(_ as String) >> 'A' }
Vyššie uvedený príklad ilustruje syntax pre vytváranie Spy pomocou rámca Spock. Pahýľ je definovaný v samotnom čase vyhlásenia.
Tiež je možné overiť špehované hovory, ako je to znázornené vo vtedajšom bloku (pomocou voľných porovnávačov argumentov, ktoré je možné definovať pre akékoľvek konkrétne argumenty).
# 2) Špionáž s využitím všetkých skutočných volaní metód
def 'illustrate spies with real method call'() { given: StudentDatabase spiedStudentDatabase = Spy(StudentDatabase.class) def studentReportGenerator = new StudentReportGenerator(spiedStudentDatabase) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'C' 1*spiedStudentDatabase.getStudentGrade('123') }
Vo vyššie uvedenom príklade, pretože sme neuviedli žiadne tvrdohlavé správanie, budú všetky hovory smerovať do skutočnej implementácie.
Záver
V tomto tutoriáli sme sa naučili všetko o vstavaných technikách Mock Stub a Spy pomocou Spockovho rámca. Spock to uľahčuje kombináciou týchto funkcií ako súčasti samotného frameworku s čitateľnejšou groovy syntaxou spolu s menším štandardným kódom.
Mocks, Stubs a Spies sa vo veľkej miere používajú pri testovaní jednotiek na zvýšenie pokrytia a testovanie alebo overenie základnej obchodnej logiky testovanej aplikácie.
Zdrojový kód aplikácie
StudentReportGenerator.java - toto je testovaná metóda / aplikácia
package app.studentScores; import java.util.List; public class StudentReportGenerator { public IStudentDatabase studentDatabase; public StudentReportGenerator(IStudentDatabase studentDatabase) { this.studentDatabase = studentDatabase; } public String calculateStudentGrade(String studentId) { String grade; // check if grade is already there in database grade = studentDatabase.getStudentGrade(studentId); if(grade!=null && !grade.isEmpty()) { return grade; } List scoreList = studentDatabase.getStudentScores(studentId); Float totalScore = 0F; if(scoreList !=null) totalScore = scoreList.stream().reduce(0F,(a,b)->a+b); if(totalScore > 90) { grade = 'A'; } else if (totalScore > 80) { grade = 'B'; } else { grade = 'C'; } // update the calculated grade in database studentDatabase.updateStudentGrade(studentId, grade); return grade; } }
IStudentDatabase.java - Rozhranie databázy
package app.studentScores; import java.util.List; public interface IStudentDatabase { List getStudentScores(String studentId); void updateStudentGrade(String studentId, String grade); String getStudentGrade(String studentId); }
StudentDatabase.java - implementácia rozhrania IStudentDatabase.java InMemory
package app.studentScores; import java.util.*; public class StudentDatabase implements IStudentDatabase { private Map scoreMap; private Map gradeMap; public StudentDatabase() { this.scoreMap = new HashMap(); this.gradeMap = new HashMap(); scoreMap.put('123', Arrays.asList(40F, 30F, 30F)); scoreMap.put('456', Arrays.asList(10F, 10F, 30F)); gradeMap.put('123', 'C'); gradeMap.put('456', 'A'); } @Override public List getStudentScores(String studentId) { return scoreMap.get(studentId); } @Override public void updateStudentGrade(String studentId, String grade) { gradeMap.put(studentId,grade); } @Override public String getStudentGrade(String studentId) { return gradeMap.get(studentId); } }
V našom pripravovanom návode uvidíme, ako integrovať rámec Spock s ostatnými testovacími rámcami a technológiami.
Výukový program PREV | NEXT Tutorial
Odporúčané čítanie
- Písanie testov jednotiek s programom Spock Framework
- Spock Interview Otázky s odpoveďami (najobľúbenejšie)
- Spock pre integráciu a funkčné testovanie so selénom
- Testovanie na základe dát alebo parametrizovanie pomocou Spock Framework
- Výukový program pre Spock: Testovanie s programom Spock a Groovy
- Najlepšia výučbová séria C # ZDARMA: Sprievodca C # pre začiatočníkov
- Testovanie záťaže s výukovými programami HP LoadRunner
- Funkcie dátumu a času v C ++ s príkladmi