Sådan Enhed test private metoder i Java og Kotlin

govind dato: DIXIT
govind dato: DIXIT

Følg

Jul 23, 2019 · 4 min læse

Ja, det er den million-dollar-spørgsmål. Sådan unit test private metoder?

skal en udvikler teste de private metoder i sin kodebase? eller at forlade dem på tillid til offentlige metoder er en måde. Hver udvikler har sin egen mening om, hvorvidt vi rent faktisk skal teste dem eller ej. Så, i en nøddeskal, spørgsmålet blev reduceret til ER ” er der nogen god tilgang, vi kan prøve for dette Job?”

så her er alle de mulige muligheder, der er tilgængelige for en udvikler til at teste private metoder til hans Java / kotlin-baserede Apps i 2019:

  1. test ikke private metoder karrus (ingen rødder, ingen sure druer)
  2. Giv metoderne offentlig adgang til karrus (Nej, Jeg vil ikke gøre dette, det er imod kodningspraksis. Jeg er en god udvikler, jeg følger best practices)
  3. brug en indlejret testklasse Kristian (dette er ikke godt at Blandet produktionskode med testkode. Skal jeg nævne igen, at jeg er en god udvikler, og jeg følger kun bedste praksis)
  4. Brug Java Reflection Karrus(ja, det virker interessant, Jeg er i for det)

På trods af den fælles tro er det faktisk muligt at få adgang til private felter og metoder i andre klasser via Java Reflection. Det er ikke engang så svært. Dette kan være meget praktisk under enhedstest.

Bemærk: Dette fungerer kun, når du kører koden som et selvstændigt Java-program, som du gør med enhedstest og almindelige applikationer. Hvis du forsøger at gøre dette inde i en Java-Applet, skal du rode rundt med SecurityManager. Men da det ikke er noget, du skal gøre meget ofte, er det udeladt af denne tekst indtil videre.

metode Parameter refleksion støtte blev tilføjet i Java 8. Kort sagt, det giver støtte til at få navnene på parametre ved runtime.

for at få adgang til et privat felt skal du ringe tilClass.getDeclaredField(String name)ellerClass.getDeclaredFields() metode. Metoderne Class.getField(String name)og Class.getFields() metoder returnerer kun offentlige felter, så de fungerer ikke. Her er et simpelt eksempel på en klasse med et privat felt, og under det Koden for at få adgang til dette felt via Java-refleksion:

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 kodeeksempel udskriver teksten "fieldValue = The Private Value”, som er værdien af det private felt privateString af PrivateObject forekomsten oprettet i begyndelsen af kodeeksemplet.

Bemærk brugen af metodenPrivateObject.class.getDeclaredField("privateString"). Det er dette metodekald, der returnerer det private felt. Denne metode returnerer kun felter, der er angivet i den pågældende klasse, ikke felter, der er angivet i nogen superklasser.

Bemærk også linjen med fed skrift. Ved at kalde Field.setAcessible(true) slukker du adgangskontrollen for denne særlige Field forekomst, kun til refleksion. Nu Kan du få adgang til det, selvom det er privat, beskyttet eller pakke omfang, selvom den, der ringer op, ikke er en del af disse anvendelsesområder. Du kan stadig ikke få adgang til feltet ved hjælp af den normale kode. Kompilatoren tillader det ikke.

adgang til Private metoder

for at få adgang til en privat metode skal du ringe tilClass.getDeclaredMethod(String name, Class parameterTypes) ellerClass.getDeclaredMethods() metode. Metoderne Class.getMethod(String name, Class parameterTypes) og Class.getMethods() metoder returnerer kun offentlige metoder, så de fungerer ikke.

Her er et simpelt eksempel på en klasse med en privat metode, og under den kode for at få adgang til denne metode via Java-refleksion:

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 kodeeksempel udskriver teksten "returnValue = The Private Value”, som er den værdi, der returneres af metoden getPrivateString() når den påberåbes på PrivateObject den forekomst, der blev oprettet i begyndelsen kode prøve.

Bemærk brugen af metodenPrivateObject.class.getDeclaredMethod("privateString"). Det er denne metode opkald, der returnerer den private metode. Denne metode returnerer kun metoder, der er erklæret i den pågældende klasse, ikke metoder, der er erklæret i nogen superklasser.

Bemærk også linjen med fed skrift. Ved at kalde Method.setAcessible(true) slukker du adgangskontrollerne for denne særlige Method forekomst, kun til refleksion. Nu Kan du få adgang til det, selvom det er privat, beskyttet eller pakke omfang, selvom den, der ringer op, ikke er en del af disse anvendelsesområder. Du kan stadig ikke få adgang til metoden ved hjælp af den normale kode. Kompilatoren tillader det ikke.

lad os prøve denne viden til nogle produktionsniveau kode.
her er klassen, der indeholder nogle private metoder, som vi vil teste.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.