Jak przeprowadzać testy jednostkowe prywatnych metod w języku Java i Kotlin

GOVIND DIXIT
GOVIND DIXIT

Postępuj zgodnie z

23 lipca 2019 · 4 min czytać

– Tak, to jest pytanie za milion dolarów. Jak przeprowadzać testy jednostkowe metod prywatnych?

czy programista powinien przetestować prywatne metody w swojej bazie kodu? lub pozostawienie ich na zaufaniu metod publicznych jest sposobem. Każdy programista ma swoje zdanie, czy faktycznie powinniśmy je testować, czy nie. Tak więc, w skrócie, pytanie zostało zredukowane do ” czy istnieje jakieś dobre podejście, które możemy spróbować w tej pracy?”

oto wszystkie możliwe opcje dostępne dla programisty, aby przetestować prywatne metody swoich aplikacji opartych na Java / kotlin w 2019 roku:

  1. nie testuj prywatnych metod 😜(bez korzeni, bez kwaśnych winogron)
  2. daj metodom publiczny dostęp 😒 (Nie, Nie zrobię tego to wbrew praktykom kodowania. Jestem dobrym programistą, stosuję najlepsze praktyki)
  3. używam zagnieżdżonej klasy testowej 😒 (nie jest to dobre do mieszania kodu produkcyjnego z kodem testowym. Czy muszę jeszcze raz wspomnieć, że jestem dobrym programistą i stosuję tylko najlepsze praktyki)
  4. używam Java Reflection 😃(tak, to wydaje się interesujące, jestem za tym)

pomimo powszechnego przekonania, że jest rzeczywiście możliwy dostęp do prywatnych pól i metod innych klas za pośrednictwem Java Reflection. To nie jest nawet takie trudne. Może to być bardzo przydatne podczas testów jednostkowych.

Uwaga: działa to tylko w przypadku uruchamiania kodu jako samodzielnej aplikacji Java, tak jak w przypadku testów jednostkowych i zwykłych aplikacji. Jeśli spróbujesz to zrobić wewnątrz apletu Java, będziesz musiał bawić się z menedżerem bezpieczeństwa. Ale ponieważ nie jest to coś, co trzeba robić bardzo często, jak na razie nie ma tego w tym tekście.

w Javie 8 dodano obsługę Reflection parametrów metody. Mówiąc najprościej, zapewnia wsparcie dla pobierania nazw parametrów w czasie wykonywania.

aby uzyskać dostęp do prywatnego pola, należy wywołać metodęClass.getDeclaredField(String name) lubClass.getDeclaredFields(). Metody Class.getField(String name) I Class.getFields() zwracają tylko publiczne pola, więc nie będą działać. Oto prosty przykład klasy z prywatnym polem, a poniżej kod dostępu do tego pola przez odbicie Javy:

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);

Ten przykład kodu wydrukuje tekst "fieldValue = The Private Value”, który jest wartością prywatnego pola privateString z "fieldValue = The Private Value”PrivateObject

instancja utworzona na początku próbki kodu.

zwróć uwagę na użycie metody PrivateObject.class.getDeclaredField("privateString"). To właśnie to wywołanie metody zwraca pole prywatne. Ta metoda zwraca tylko pola zadeklarowane w danej klasie, a nie pola zadeklarowane w żadnej superklasie.

zwróć też uwagę na linię pogrubioną. WywołującField.setAcessible(true) wyłączasz sprawdzanie dostępu dla tej konkretnej instancjiField, tylko dla odbicia. Teraz możesz uzyskać do niego dostęp, nawet jeśli jest to obszar prywatny, chroniony lub pakiet, nawet jeśli dzwoniący nie jest częścią tych zakresów. Nadal nie można uzyskać dostępu do pola przy użyciu normalnego kodu. Kompilator na to nie pozwoli.

dostęp do prywatnych metod

aby uzyskać dostęp do prywatnej metody, musisz wywołaćClass.getDeclaredMethod(String name, Class parameterTypes) lubClass.getDeclaredMethods() metoda. Metody Class.getMethod(String name, Class parameterTypes) I Class.getMethods() zwracają tylko publiczne metody, więc nie będą działać.

Oto prosty przykład klasy z prywatną metodą, a poniżej kod dostępu do tej metody poprzez Java Reflection:

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);

Ten przykład kodu wyświetli tekst "returnValue = The Private Value”, który jest wartością zwracaną przez metodę getPrivateString() po wywołaniu naPrivateObject instancja utworzona na początku kodu próbka.

zwróć uwagę na zastosowanie metody PrivateObject.class.getDeclaredMethod("privateString"). To właśnie wywołanie tej metody zwraca metodę prywatną. Ta metoda zwraca tylko metody zadeklarowane w danej klasie, a nie metody zadeklarowane w żadnej klasie nadrzędnej.

zwróć też uwagę na linię pogrubioną. WywołującMethod.setAcessible(true) wyłączasz sprawdzanie dostępu dla tej konkretnej instancjiMethod, tylko dla refleksji. Teraz możesz uzyskać do niego dostęp, nawet jeśli jest to obszar prywatny, chroniony lub pakiet, nawet jeśli dzwoniący nie jest częścią tych zakresów. Nadal nie można uzyskać dostępu do metody przy użyciu normalnego kodu. Kompilator na to nie pozwoli.

spróbujmy tej wiedzy do jakiegoś kodu produkcyjnego.
oto Klasa zawierająca kilka prywatnych metod, które chcemy przetestować.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.