Igen, Ez az egymillió dolláros kérdés. Hogyan egység teszt privát módszerek?
a fejlesztőnek tesztelnie kell a privát módszereket a kódbázisában? vagy hagyja őket a nyilvános módszerek bizalmára. Minden fejlesztőnek megvan a saját véleménye arról, hogy valóban teszteljük-e őket vagy sem. Így, dióhéjban, a kérdés redukálódott: “létezik-e valamilyen jó megközelítés, amelyet megpróbálhatunk erre a munkára?”
tehát itt található az összes lehetséges lehetőség a fejlesztő számára, hogy tesztelje Java / kotlin alapú alkalmazásainak privát módszereit 2019-ben:
- ne tesztelje a privát módszereket(nincs gyökér, nincs savanyú szőlő)
- adjon nyilvános hozzáférést a módszerekhez (nem, ezt nem fogom megtenni, ez ellentétes a kódolási gyakorlatokkal. Jó fejlesztő vagyok, követem a legjobb gyakorlatokat)
- beágyazott tesztosztályt használjon (ez nem jó a gyártási kód keveréséhez a tesztkóddal. Még egyszer meg kell említenem, hogy jó fejlesztő vagyok, és csak a legjobb gyakorlatokat követem)
- használja a Java reflexiót(Igen, ez érdekesnek tűnik, benne vagyok)
annak ellenére, hogy a közhiedelem szerint valójában lehetséges más osztályok privát mezőinek és módszereinek elérése a Java Reflection segítségével. Ez nem is olyan nehéz. Ez nagyon hasznos lehet az egység tesztelése során.
Megjegyzés: Ez csak akkor működik, ha a kódot önálló Java alkalmazásként futtatja, mint az egységteszteknél és a szokásos alkalmazásoknál. Ha megpróbálja ezt egy Java Kisalkalmazáson belül megtenni, akkor a Securitymanagerrel kell babrálnia. De mivel ez nem olyasmi, amit nagyon gyakran kell tennie, eddig kimaradt ebből a szövegből.
Metódusparaméter reflexiós támogatást adtak hozzá a Java 8-hoz. Egyszerűen fogalmazva, támogatást nyújt a paraméterek nevének futtatásához.
privát mező eléréséhez meg kell hívnia aClass.getDeclaredField(String name)
vagyClass.getDeclaredFields()
módszert. A Class.getField(String name)
és Class.getFields()
metódusok csak nyilvános mezőket adnak vissza, így nem fognak működni. Itt van egy egyszerű példa egy privát mezővel rendelkező osztályra, amely alatt a kód a Java Reflection segítségével érhető el:
public class PrivateObject {private String privateString = null;public PrivateObject(String privateString) {
this.privateString = privateString;
}
}PrivateObject privateObject = new PrivateObject("The Private Value");Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");privateStringField.setAccessible(true);String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
Ez a kódpélda kinyomtatja a "fieldValue = The Private Value”
szöveget, amely a privateString
privát mező értéke privateString
a PrivateObject
a kódminta elején létrehozott példány.
figyeljük meg a módszer használatátPrivateObject.class.getDeclaredField("privateString")
. Ez a módszerhívás adja vissza a privát mezőt. Ez a módszer csak az adott osztályban deklarált mezőket adja vissza, a szuperosztályokban deklarált mezőket nem.
figyelje meg a sort félkövéren is. A Field.setAcessible(true)
meghívásával kikapcsolja az adott Field
példány hozzáférési ellenőrzését, csak reflexió céljából. Most akkor is elérheti, ha privát, védett vagy csomag hatóköre van, még akkor is, ha a hívó fél nem része ezeknek a hatóköröknek. Még mindig nem tudja elérni a mezőt a normál kóddal. A fordító nem engedi.
privát módszerek elérése
privát módszer eléréséhez meg kell hívnia a Class.getDeclaredMethod(String name, Class parameterTypes)
vagy Class.getDeclaredMethods()
módszert. A Class.getMethod(String name, Class parameterTypes)
és Class.getMethods()
metódusok csak nyilvános metódusokat adnak vissza, így nem fognak működni.
itt van egy egyszerű példa egy privát módszerrel rendelkező osztályra, alatta pedig a kód, amely a módszer eléréséhez Java reflexió:
public class PrivateObject {private String privateString = null;public PrivateObject(String privateString) {
this.privateString = privateString;
}private String getPrivateString(){
return this.privateString;
}
}PrivateObject privateObject = new PrivateObject("The Private Value");Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);privateStringMethod.setAccessible(true);String returnValue = (String)
privateStringMethod.invoke(privateObject, null);System.out.println("returnValue = " + returnValue);
Ez a kódpélda kinyomtatja a "returnValue = The Private Value”
szöveget, amely a módszer által visszaadott érték getPrivateString()
amikor a PrivateObject
a PrivateObject
figyeljük meg a módszer használatát PrivateObject.class.getDeclaredMethod("privateString")
. Ez a módszerhívás adja vissza a privát módszert. Ez a módszer csak az adott osztályban deklarált metódusokat adja vissza, a szuperosztályokban deklarált metódusokat nem.
figyelje meg a sort félkövéren is. A Method.setAcessible(true)
meghívásával kikapcsolja az adott Method
példány hozzáférési ellenőrzését, csak reflexió céljából. Most akkor is elérheti, ha privát, védett vagy csomag hatóköre van, még akkor is, ha a hívó fél nem része ezeknek a hatóköröknek. Még mindig nem férhet hozzá a módszerhez a normál kód használatával. A fordító nem engedi.
próbáljuk ki ezt a tudást valamilyen termelési szintű kódra.
itt van az osztály, amely néhány privát metódust tartalmaz, amelyeket tesztelni akarunk.