mocking private static
Naučte se zesměšňovat soukromé, statické a neplatné metody v Mockito s příklady:
V této sérii praktických cvičení Návody na Mockito , podívali jsme se na různé typy Mockito Matcherů v posledním tutoriálu.
Obecně lze říci, že posměšné soukromé a statické metody spadají do kategorie neobvyklých posměšků.
Pokud vyvstane potřeba zesměšňovat soukromé a statické metody / třídy, znamená to špatně refaktorovaný kód a ve skutečnosti to není testovatelný kód a je pravděpodobné, že nějaký starší kód, který nebyl zvyklý, je velmi vhodný pro jednotkové testy.
Jak již bylo řečeno, stále existuje podpora pro Mocking soukromé a statické metody několika rámci pro testování jednotek, jako je PowerMockito (a ne přímo Mockito).
Vysmívající se metody „void“ jsou běžné, protože mohou existovat metody, které v podstatě nic nevracejí, například aktualizace řádku databáze (považujte to za operaci PUT koncového bodu rozhraní Rest API, která přijímá vstup a nevrací žádný výstup).
Mockito poskytuje plnou podporu pro posměšné metody neplatnosti, které uvidíme s příklady v tomto článku.
jak tisknout obsah pole java
Co se naučíte:
- Powermock - krátký úvod
- Vysmívat se soukromým metodám
- Falešné statické metody
- Mocking Void Methods
- tipy a triky
- Závěr
- Doporučené čtení
Powermock - Stručný úvod
Pro Mockito neexistuje žádná přímá podpora pro falešné soukromé a statické metody. Abyste mohli otestovat soukromé metody, budete muset refaktorovat kód změnit přístup k chráněnému (nebo balíčku) a budete se muset vyhnout statickým / konečným metodám.
Mockito podle mého názoru úmyslně neposkytuje podporu pro tyto druhy falešných zpráv, protože používání těchto druhů konstruktů kódu jsou pachy kódu a špatně navržený kód.
Existují však rámce, které podporují zesměšňování soukromých a statických metod.
Powermock rozšiřuje možnosti dalších rámců, jako jsou EasyMock a Mockito, a poskytuje schopnost simulovat statické a soukromé metody.
# 1) Jak: Powermock to dělá pomocí vlastní manipulace s bytecode, aby podporoval posměšné soukromé a statické metody, konečné třídy, konstruktory atd.
# 2) Podporované balíčky: Powermock poskytuje 2 rozšiřující API - jedno pro Mockito a druhé pro easyMock. Kvůli tomuto článku budeme psát příklady s rozšířením Mockito pro falešný výkon.
# 3) Syntaxe :Powermockito má téměř podobnou syntaxi jako Mockito, kromě některých dalších metod pro zesměšňování statických a soukromých metod.
# 4) Nastavení Powermockito
Aby bylo možné zahrnout knihovnu Mockito do projektů založených na gradlech, níže jsou zahrnuty knihovny:
testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.4' testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.4'
Podobné závislosti jsou k dispozici také pro maven.
Powermock-api-mockito2 - Knihovna musí obsahovat rozšíření Mockito pro Powermockito.
Powermock-modul-junit4 - Modul je povinen zahrnout PowerMockRunner (což je vlastní běžec, který se používá pro spouštění testů s PowerMockito).
Zde je důležité si uvědomit, že PowerMock nepodporuje testovací běh Junit5. Proto je třeba testy zapsat proti Junit4 a testy je třeba provést pomocí nástroje PowerMockRunner.
Chcete-li použít PowerMockRunner - testovací třída musí být anotována @RunWith (PowerMockRunner.class)
Nyní pojďme diskutovat a vysmívat se soukromým, statickým a neplatným metodám podrobně!
Vysmívat se soukromým metodám
Zesměšňování soukromých metod, které se interně volají z testované metody, může být v určitých časech nevyhnutelné. Pomocí nástroje powermockito je to možné a ověření se provádí pomocí nové metody s názvem ‚verifyPrivate '
Pojďme vzít anPříklad kde testovaná metoda volá soukromou metodu (která vrací boolean). Aby bylo možné tuto metodu stub vrátit na hodnotu true / false v závislosti na testu, je třeba v této třídě nastavit stub.
V tomto příkladu je testovaná třída vytvořena jako špionážní instance s výsměchem na několik vyvolání rozhraní a vyvolání soukromé metody.
Důležité body pro Mock Private Method:
# 1) Testovací metoda nebo testovací třída musí být anotována pomocí @ PrepareForTest (ClassUnderTest). Tato anotace říká powerMockitu, aby připravil určité třídy pro testování.
Budou to většinou ty třídy, které musí být Bytecode manipulated . Typicky pro závěrečné třídy, třídy obsahující soukromé a / nebo statické metody, u nichž se vyžaduje vysmívání během testování.
Příklad:
@PrepareForTest(PriceCalculator.class)
#dva) Chcete-li nastavit stub na soukromé metodě.
Syntax - when (mock or spy instance, “privateMethodName”). thenReturn (// návratová hodnota)
Příklad:
when (priceCalculatorSpy, 'isCustomerAnonymous').thenReturn(false);
# 3) Chcete-li ověřit skrytou soukromou metodu.
Syntax - verifyPrivate (mockedInstance) .invoke („privateMethodName“)
Příklad:
verifyPrivate (priceCalculator).invoke('isCustomerAnonymous');
Kompletní testovací vzorek: Pokračujeme ve stejném příkladu z předchozích článků, kde má priceCalculator několik zesměšňovaných závislostí, jako itemService, userService atd.
Vytvořili jsme novou metodu nazvanou - countPriceWithPrivateMethod, která volá soukromou metodu uvnitř stejné třídy a vrátí, zda je zákazník anonymní nebo ne.
@Test @PrepareForTest(PriceCalculator.class) public void calculatePriceForAnonymous_witStubbedPrivateMethod_returnsCorrectPrice() throws Exception { // Arrange ItemSku item1 = new ItemSku(); item1.setApplicableDiscount(5.00); item1.setPrice(100.00); double expectedPrice = 90.00; // Setting up stubbed responses using mocks when(priceCalculatorSpy, 'isCustomerAnonymous').thenReturn(false); when(mockedItemService.getItemDetails(123)).thenReturn(item1); // Act double actualDiscountedPrice = priceCalculatorSpy.calculatePriceWithPrivateMethod(123); // Assert verifyPrivate(priceCalculator).invoke('isCustomerAnonymous'); assertEquals(expectedPrice, actualDiscountedPrice); }
Falešné statické metody
Statické metody lze zesměšňovat podobným způsobem, jaký jsme viděli u soukromých metod.
Když testovaná metoda zahrnuje použití statické metody ze stejné třídy (nebo z jiné třídy), budeme muset tuto třídu zahrnout do anotace PreparForTest před Testem (nebo na testovací třídě).
Důležité body pro falešné statické metody:
# 1) Testovací metoda nebo testovací třída musí být anotována pomocí @ PrepareForTest (ClassUnderTest). Podobně jako u posměšných soukromých metod / tříd je to nutné i pro statické třídy.
#dva) U statických metod je vyžadován jeden další krok - mockStatic (// název statické třídy)
Příklad:
mockStatic(DiscountCategoryFinder.class)
# 3) Chcete-li nastavit stub na statickou metodu, je to stejně dobré jako stubbing jakoukoli metodu na jakékoli jiné falešné instance rozhraní / třídy.
Například: Chcete-li získat getDiscountCategory () (který vrací výčet DiscountCategory s hodnotami PREMIUM & GENERAL) statickou metodu třídy DiscountCategoryFinder, jednoduše stub následujícím způsobem:
when (DiscountCategoryFinder. getDiscountCategory ()).thenReturn(DiscountCategory. PREMIUM );
# 4) K ověření falešného nastavení finální / statické metody lze použít metodu verifyStatic ().
Příklad:
verifyStatic (DiscountCategoryFinder.class, times (1));
Mocking Void Methods
Nejprve se pokusme pochopit, jaké druhy případů použití mohou zahrnovat metody stubbing void:
# 1) Například volání metod - která během procesu odešle e-mailové upozornění.
Například :Předpokládejme, že změníte heslo pro svůj účet internetového bankovnictví, jakmile bude změna úspěšná, obdržíte oznámení prostřednictvím svého e-mailu.
To lze považovat za / changePassword jako volání POST do API banky, které zahrnuje volání metody void pro odeslání e-mailového oznámení zákazníkovi.
#dva) Dalším běžným příkladem volání metody void jsou aktualizované požadavky na DB, které přijímají určitý vstup a nic nevracejí.
Metody stubbing void (tj. Metody, které nic nevracejí nebo jinak vyvolávají výjimku), lze zpracovat pomocí funkce doNothing (), doThrow () a doAnswer (), doCallRealMethod () . Vyžaduje, aby byl pahýl nastaven pomocí výše uvedených metod podle očekávání testu.
Všimněte si také, že všechna volání metody void jsou ve výchozím nastavení zesměšňována na doNothing (). Proto, i když se neprovádí explicitní falešné nastavení NEPLATNÝ volání metod, výchozí chování je stále to doNothing ().
Podívejme se na příklady všech těchto funkcí:
U všech příkladů předpokládejme, že existuje třída StudentScoreUpdates který má metodu countSumAndStore (). Tato metoda vypočítá součet skóre (jako vstup) a zavolá a prázdnota metoda updateScores () na instanci databaseImplementation.
public class StudentScoreUpdates { public IDatabase databaseImpl; public StudentScoreUpdates(IDatabase databaseImpl) { this.databaseImpl = databaseImpl; } public void calculateSumAndStore(String studentId, int() scores) { int total = 0; for(int score : scores) { total = total + score; } // write total to DB databaseImpl.updateScores(studentId, total); } }
Budeme psát jednotkové testy pro falešné volání metody s níže uvedenými příklady:
# 1) dělat nic () - doNothing () je výchozí chování pro volání metody void v Mockito, tj. I když ověříte volání metody void (bez výslovného nastavení void na doNothing (), ověření bude stále úspěšné)
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb() { // Arrange studentScores = new StudentScoreUpdates(mockDatabase); int() scores = {60,70,90}; Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); // Act studentScores.calculateSumAndStore('student1', scores); // Assert Mockito.verify(mockDatabase, Mockito.times(1)).updateScores(anyString(), anyInt()); }
Další použití spolu s doNothing ()
na) Když je metoda void volána vícekrát a chcete nastavit různé odpovědi pro různá vyvolání, například - doNothing () pro první vyvolání a vyvolání výjimky pro další vyvolání.
Například :Nastavit předstíranou takto:
Mockito. doNothing ().doThrow(new RuntimeException()).when(mockDatabase).updateScores( anyString (), anyInt ());
b) Pokud chcete zachytit argumenty, pomocí kterých byla metoda void volána, měla by být použita funkce ArgumentCaptor v Mockito. To poskytuje další ověření argumentů, pomocí kterých byla metoda volána.
Příklad s ArgumentCaptor:
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb() { // Arrange studentScores = new StudentScoreUpdates(mockDatabase); int() scores = {60,70,90}; Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); ArgumentCaptor studentIdArgument = ArgumentCaptor.forClass(String.class); // Act studentScores.calculateSumAndStore('Student1', scores); // Assert Mockito.verify(mockDatabase, Mockito.times(1)).updateScores(studentIdArgument.capture(), anyInt()); assertEquals('Student1', studentIdArgument.getValue()); }
# 2) doThrow ()- To je užitečné, když chcete jednoduše vyvolat výjimku, když je metoda void vyvolána z testované metody.
Například:
Mockito.doThrow(newRuntimeException()).when(mockDatabase).updateScores ( anyString (), anyInt ());
# 3) doAnswer ()- doAnswer () jednoduše poskytuje rozhraní pro provádění vlastní logiky.
Např. Úprava určité hodnoty prostřednictvím předaných argumentů, vrácení vlastních hodnot / dat, které normální stub nemohl vrátit, zejména pro metody void.
Pro účely demonstrace - vložil jsem metodu updateScores () void, abych vrátil „ Odpovědět() ”A vytiskne hodnotu jednoho z argumentů, které měly být předány při volání metody.
Příklad kódu:
@Test public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb() { // Arrange studentScores = new StudentScoreUpdates(mockDatabaseImpl); int() scores = {60,70,90}; Mockito.doCallRealMethod().when(mockDatabaseImpl).updateScores(anyString(), anyInt()); doAnswer(invocation -> { Object() args = invocation.getArguments(); Object mock = invocation.getMock(); System.out.println(args(0)); return mock; }).when(mockDatabaseImpl).updateScores(anyString(), anyInt()); // Act studentScores.calculateSumAndStore('Student1', scores); // Assert Mockito.verify(mockDatabaseImpl, Mockito.times(1)).updateScores(anyString(), anyInt()); }
# 4) doCallRealMethod ()- Částečné falešné zprávy jsou podobné pahýlům (kde můžete pro některé metody volat skutečné metody a zbytek vyřadit).
Pro metody void poskytuje mockito speciální funkci nazvanou doCallRealMethod (), kterou lze použít, když se pokoušíte nastavit falešný výraz. Co to udělá, je zavolat metodu real void se skutečnými argumenty.
Například:
Mockito. doCallRealMethod ().when(mockDatabaseImpl).updateScores( anyString (), anyInt ());
tipy a triky
# 1) Včetně více statických tříd ve stejné zkušební metodě / třídě- Používání PowerMockito pokud je potřeba zesměšňovat více tříd Static of Final, pak názvy tříd v @ PrepareForTest anotaci lze uvést jako hodnotu oddělenou čárkami jako pole (v podstatě přijímá pole názvů tříd).
Příklad:
@PrepareForTest({PriceCalculator.class, DiscountCategoryFinder.class})
Jak je znázorněno v příkladu výše, předpokládejme, že PriceCalculator a DiscountCategoryFinder jsou konečné třídy, které je třeba zesměšňovat. Oba z nich lze v anotaci PrepareForTest zmínit jako řadu tříd a lze je testovat v testovací metodě.
# 2) PrepareForTest Atribut Umístění - Umístění tohoto atributu je důležité s ohledem na druh testů, které jsou zahrnuty ve třídě Test.
Pokud všechny testy potřebují použít stejnou finální třídu, pak má smysl zmínit tento atribut na úrovni testovací třídy, což jednoduše znamená, že připravená třída bude k dispozici všem testovacím metodám. Na rozdíl od toho, je-li u testovací metody uvedena anotace, bude k dispozici pouze pro konkrétní testy
Závěr
V tomto kurzu jsme diskutovali o různých přístupech k simulovaným statickým, konečným a neplatným metodám.
Ačkoli použití mnoha statických nebo konečných metod brání testovatelnosti, stále existuje podpora pro testování / zesměšňování, která pomáhá při vytváření testů jednotek, aby se dosáhlo větší důvěry v kód / aplikaci i pro starší kód, který se obvykle nepoužívá být navrženy pro testovatelnost.
Pro statické a finální metody Mockito nemá podporu out of box, ale knihovny jako PowerMockito (které zdědí hodně věcí od Mockita) takovou podporu poskytují a pro podporu těchto funkcí musí skutečně provádět manipulaci s bytecode.
Mockito po vybalení z krabice podporuje metody stubbing void a poskytuje různé metody jako doNothing, doAnswer, doThrow, doCallRealMethod atd. A lze je použít podle požadavku testu.
Nejčastěji kladené otázky týkající se rozhovorů s Mockito jsou popsány v našem dalším výukovém programu.
Výukový program PREV | DALŠÍ výuka
nejlepší google chrome pop up blocker
Doporučené čtení
- Výukový program Mockito: Rámec Mockito pro zesměšňování při testování jednotek
- Top 12 Mockito Interview Questions (Mocking Framework Interview)
- Statické v C ++
- Java vlákna s metodami a životním cyklem
- Vytváření mocků a špiónů v mockito s příklady kódu
- Různé typy Matchers poskytované Mockito
- Metody a techniky prevence defektů
- Jak používat metody v SoapUI pro hromadné provádění testu - SoapUI Tutorial # 10