Come Unità di test privati metodi in Java e Kotlin

GOVIND DIXIT
GOVIND DIXIT

Seguire

Lug 23, 2019 · 4 min leggere

Sì, Questa è la domanda un milione di dollari. Come unit test metodi privati?

Uno sviluppatore dovrebbe testare i metodi privati nella sua base di codice? o lasciarli sulla fiducia dei metodi pubblici è un modo. Ogni sviluppatore ha la sua opinione sul fatto che dovremmo effettivamente testarli o meno. Quindi, in poche parole, la domanda è stata ridotta a ” Esiste un buon approccio che possiamo provare per questo lavoro?”

Quindi, ecco tutte le possibili opzioni disponibili per uno sviluppatore per testare i metodi privati delle sue app basate su Java / kotlin nel 2019:

  1. Non testare metodi privati 😜(Senza radici, senza uva acerba)
  2. Dare ai metodi l’accesso pubblico 😒 (No, non lo farò è contro le pratiche di codifica. Sono un buon sviluppatore, seguo le migliori pratiche)
  3. Usa una classe di test nidificata 😒 (Questo non va bene per il codice di produzione misto con il codice di test. Devo menzionare di nuovo che sono un buon sviluppatore e seguo solo le migliori pratiche)
  4. Usa Java Reflection 😃(Sì, questo sembra interessante ci sto dentro)

Nonostante la credenza comune che sia effettivamente possibile accedere a campi privati e metodi di altre classi tramite Java Reflection. Non è nemmeno così difficile. Questo può essere molto utile durante il test delle unità.

Nota: funziona solo quando si esegue il codice come applicazione Java autonoma, come si fa con i test unitari e le applicazioni regolari. Se provi a farlo all’interno di un’applet Java, dovrai armeggiare con SecurityManager. Ma, dal momento che non è qualcosa che devi fare molto spesso, è rimasto fuori da questo testo finora.

Il supporto per la riflessione dei parametri del metodo è stato aggiunto in Java 8. In poche parole, fornisce supporto per ottenere i nomi dei parametri in fase di esecuzione.

Per accedere a un campo privato è necessario chiamare il metodoClass.getDeclaredField(String name)oClass.getDeclaredFields(). I metodi Class.getField(String name) e Class.getFields() restituiscono solo campi pubblici, quindi non funzioneranno. Ecco un semplice esempio di una classe con un campo privato, e di seguito il codice per accedere a tale campo di via Java Riflessione:

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

in Questo esempio di codice stamperà il testo "fieldValue = The Private Value” quale è il valore del campo privato privateString di PrivateObject l’istanza creata all’inizio del codice di esempio.

Si noti l’uso del metodo PrivateObject.class.getDeclaredField("privateString"). È questa chiamata al metodo che restituisce il campo privato. Questo metodo restituisce solo i campi dichiarati in quella particolare classe, non i campi dichiarati in qualsiasi superclasse.

Si noti la linea in grassetto troppo. Chiamando Field.setAcessible(true)si disabilitano i controlli di accesso per questa particolare istanzaField, solo per riflessione. Ora è possibile accedervi anche se è privato, protetto o ambito del pacchetto, anche se il chiamante non fa parte di tali ambiti. Non è ancora possibile accedere al campo utilizzando il codice normale. Il compilatore non lo permetterà.

Accesso ai metodi privati

Per accedere a un metodo privato è necessario chiamare il metodoClass.getDeclaredMethod(String name, Class parameterTypes) oClass.getDeclaredMethods(). I metodi Class.getMethod(String name, Class parameterTypes)eClass.getMethods() restituiscono solo metodi pubblici, quindi non funzioneranno.

Ecco un semplice esempio di una classe con un metodo privato, e di seguito il codice per accedere a tale metodo tramite 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);

in Questo esempio di codice stamperà il testo "returnValue = The Private Value”, che è il valore restituito dal metodo getPrivateString() quando viene richiamato il PrivateObject l’istanza creata all’inizio del codice di esempio.

Si noti l’uso del metodo PrivateObject.class.getDeclaredMethod("privateString"). È questa chiamata al metodo che restituisce il metodo privato. Questo metodo restituisce solo i metodi dichiarati in quella particolare classe, non i metodi dichiarati in nessuna superclasse.

Si noti la linea in grassetto troppo. Chiamando Method.setAcessible(true)si disattiva i controlli di accesso per questa particolare istanzaMethod, solo per riflessione. Ora è possibile accedervi anche se è privato, protetto o ambito del pacchetto, anche se il chiamante non fa parte di tali ambiti. Non è ancora possibile accedere al metodo utilizzando il codice normale. Il compilatore non lo permetterà.

Proviamo questa conoscenza con un codice a livello di produzione.
Ecco la classe contenente alcuni metodi privati che vogliamo testare.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.