Jul 23, 2019 · 4 min lese
ja, dette er million-dollar spørsmålet. Hvordan enhet test private metoder?
Skal en utvikler teste de private metodene i kodebasen sin? eller å forlate dem på tillit fra offentlige metoder er en måte. Hver utvikler har sin egen mening om at om vi faktisk skal teste dem eller ikke. Så I et nøtteskall ble spørsmålet redusert til «Er det noen god tilnærming vi kan prøve for Denne Jobben?»
Så, her er alle mulige alternativer tilgjengelig for en utvikler for å teste private metoder for Sine Java / kotlin – Baserte Apper i 2019:
- ikke test private metoder 😜(ingen røtter, ingen sure druer)
- Gi metodene offentlig tilgang 😒 (Nei, jeg vil ikke gjøre dette det er mot kodingspraksis. Jeg er en god utvikler, jeg følger beste praksis)
- Bruk en nestet testklasse 😒 (Dette er ikke bra å blande produksjonskode med testkode. Trenger jeg å nevne igjen at jeg er en god utvikler og jeg følger bare beste praksis)
- Bruk Java Refleksjon 😃(Ja, dette virker interessant jeg er i for det)
Til tross for den vanlige troen er det faktisk mulig å få tilgang til private felt og metoder for andre klasser Via Java Refleksjon. Det er ikke engang så vanskelig. Dette kan være svært nyttig under enhetstesting.
Merk: dette fungerer bare når du kjører koden som et Frittstående Java-program, som du gjør med enhetstester og vanlige applikasjoner. Hvis du prøver å gjøre dette inne I En Java-Applet, må du fla med SecurityManager. Men siden det ikke er noe du trenger å gjøre veldig ofte, er det utelatt av denne teksten så langt.
Metode Parameter Refleksjon støtte ble lagt I Java 8. Enkelt sagt, det gir støtte for å få navnene på parametere under kjøring.
for å få tilgang til et privat felt må du ringeClass.getDeclaredField(String name)
ellerClass.getDeclaredFields()
– metoden. MetodeneClass.getField(String name)
ogClass.getFields()
metodene returnerer bare offentlige felt, så de vil ikke fungere. Her er et enkelt eksempel på en klasse med et privat felt, og under at koden for å få tilgang til dette feltet via Java Refleksjon:
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);
dette kodeeksemplet vil skrive ut teksten "fieldValue = The Private Value”
, som er verdien av det private feltet privateString
av PrivateObject
forekomsten som ble opprettet i begynnelsen av kodeeksemplet.
Legg Merke til bruken av metoden PrivateObject.class.getDeclaredField("privateString")
. Det er denne metodekallet som returnerer det private feltet. Denne metoden returnerer bare felt deklarert i den aktuelle klassen, ikke felt deklarert i noen superklasser.
Legg Merke til linjen i fet skrift også. Ved å ringe Field.setAcessible(true)
slår du av tilgangskontrollene for denne spesielleField
forekomst, bare for refleksjon. Nå kan du få tilgang til det selv om det er privat, beskyttet eller pakke omfang, selv om den som ringer ikke er en del av disse omfang. Du kan fortsatt ikke få tilgang til feltet ved hjelp av den vanlige koden. Kompilatoren vil ikke tillate det.
Tilgang Til Private Metoder
for å få tilgang til en privat metode må du ringe Class.getDeclaredMethod(String name, Class parameterTypes)
eller Class.getDeclaredMethods()
metoden. MetodeneClass.getMethod(String name, Class parameterTypes)
ogClass.getMethods()
metodene returnerer bare offentlige metoder, så de vil ikke fungere.
her er et enkelt eksempel på en klasse med en privat metode, og under at koden for å få tilgang til denne metoden Via Java Refleksjon:
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);
dette kodeeksemplet vil skrive ut teksten "returnValue = The Private Value”
, som er verdien som returneres med metoden getPrivateString()
når den startes på PrivateObject
forekomsten opprettet i begynnelsen av kodeeksempel.
Legg Merke til bruken av metoden PrivateObject.class.getDeclaredMethod("privateString")
. Det er denne metodekallet som returnerer den private metoden. Denne metoden returnerer bare metoder deklarert i den aktuelle klassen, ikke metoder deklarert i noen superklasser.
Legg Merke til linjen i fet skrift også. Ved å ringeMethod.setAcessible(true)
slår du av tilgangskontrollene for denne spesielleMethod
forekomst, bare for refleksjon. Nå kan du få tilgang til det selv om det er privat, beskyttet eller pakke omfang, selv om den som ringer ikke er en del av disse omfang. Du kan fortsatt ikke få tilgang til metoden ved hjelp av vanlig kode. Kompilatoren vil ikke tillate det.
La oss prøve denne kunnskapen til noen produksjonsnivåkode.
her er klassen som inneholder noen private metoder som vi ønsker å teste.