da, aceasta este întrebarea de milioane de dolari. Cum să testați metodele private?
ar trebui un dezvoltator să testeze metodele private în baza sa de cod? sau lăsându-le pe încrederea metodelor publice este o cale. Fiecare dezvoltator are propria opinie că dacă ar trebui să le testăm sau nu. Deci, pe scurt, întrebarea a fost redusă la este ” Există vreo abordare bună pe care o putem încerca pentru acest loc de muncă?”
deci, iată toate opțiunile posibile disponibile unui dezvoltator pentru a testa metodele private ale aplicațiilor sale bazate pe Java / kotlin în 2019:
- nu testați metode private(fără rădăcini, fără struguri acri)
- dați metodelor acces public (nu, Nu voi face acest lucru este împotriva practicilor de codificare. Sunt un dezvoltator bun, urmez cele mai bune practici)
- utilizați o clasă de testare imbricată (acest lucru nu este bun pentru codul de producție mixt cu codul de testare. Trebuie să menționez din nou că sunt un dezvoltator bun și urmez doar cele mai bune practici)
- utilizați Java Reflection(Da, acest lucru pare interesant sunt pentru el)
În ciuda credinței comune, este de fapt posibil să accesați câmpuri private și metode ale altor clase prin reflecție Java. Nu este chiar atât de dificil. Acest lucru poate fi foarte util în timpul testării unității.
Notă: Acest lucru funcționează numai atunci când rulează codul ca o aplicație Java independent, așa cum faci cu teste unitare și aplicații obișnuite. Dacă încercați să faceți acest lucru într-un Applet Java, va trebui să vă jucați cu SecurityManager. Dar, deoarece acest lucru nu este ceva ce trebuie să faceți foarte des, este lăsat în afara acestui text până acum.
metoda de sprijin parametru reflecție a fost adăugat în Java 8. Pur și simplu, oferă suport pentru obținerea numelor parametrilor în timpul rulării.
pentru a accesa un câmp privat, va trebui să apelați metoda Class.getDeclaredField(String name)
sau Class.getDeclaredFields()
. Metodele Class.getField(String name)
și Class.getFields()
returnează doar câmpurile publice, deci nu vor funcționa. Aici este un exemplu simplu de o clasă cu un câmp privat, și mai jos că codul pentru a accesa acest câmp prin reflecție Java:
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);
acest exemplu de cod va imprima textul "fieldValue = The Private Value”
, care este valoarea câmpului privat privateString
a PrivateObject
instanța creată la începutul eșantionului de cod.
observați utilizarea metodeiPrivateObject.class.getDeclaredField("privateString")
. Este acest apel metodă care returnează câmpul privat. Această metodă returnează numai câmpurile declarate în acea clasă particulară, nu câmpurile declarate în nicio superclasă.
observați și linia cu caractere aldine. ApelândField.setAcessible(true)
dezactivați verificările de acces pentru această instanțăField
, numai pentru reflecție. Acum îl puteți accesa chiar dacă este privat, protejat sau pachet, chiar dacă apelantul nu face parte din aceste domenii. Încă nu puteți accesa câmpul folosind codul normal. Compilatorul nu va permite acest lucru.
accesarea metodelor Private
pentru a accesa o metodă privată, va trebui să apelați metodaClass.getDeclaredMethod(String name, Class parameterTypes)
sauClass.getDeclaredMethods()
. Metodele Class.getMethod(String name, Class parameterTypes)
și Class.getMethods()
returnează doar metodele publice, deci nu vor funcționa.
aici este un exemplu simplu de o clasă cu o metodă privată, și mai jos că codul pentru a accesa această metodă prin reflecție Java:
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);
acest exemplu de cod va imprima textul "returnValue = The Private Value”
, care este valoarea returnată prin metoda getPrivateString()
atunci când este invocată pe PrivateObject
instanța creată la începutul codului mostră.
observați utilizarea metodeiPrivateObject.class.getDeclaredMethod("privateString")
. Este acest apel metodă care returnează metoda privată. Această metodă returnează numai metodele declarate în acea clasă particulară, nu metodele declarate în nicio superclasă.
observați și linia cu caractere aldine. ApelândMethod.setAcessible(true)
dezactivați verificările de acces pentru această instanțăMethod
, numai pentru reflecție. Acum îl puteți accesa chiar dacă este privat, protejat sau pachet, chiar dacă apelantul nu face parte din aceste domenii. Încă nu puteți accesa metoda folosind codul normal. Compilatorul nu va permite acest lucru.
să încercăm aceste cunoștințe la un cod de nivel de producție.
aici este clasa care conține câteva metode private pe care vrem să le testăm.