Sí, Esta es la pregunta del millón. ¿Cómo probar métodos privados unitarios?
¿Debería un desarrollador probar los métodos privados en su base de código? o dejarlos en la confianza de los métodos públicos es una manera. Cada desarrollador tiene su propia opinión de si deberíamos probarlos o no. Así que, en pocas palabras, la pregunta se redujo a «¿Existe algún buen enfoque que podamos intentar para este trabajo?»
Entonces, aquí están todas las opciones posibles disponibles para que un desarrollador pruebe métodos privados de sus aplicaciones basadas en Java / kotlin en 2019:
- No pruebe métodos privados Sin raíces, sin uvas agrias)
- Dé acceso público a los métodos Give (No, no lo haré, es contra las prácticas de codificación. Soy un buen desarrollador, sigo las mejores prácticas)
- Use una clase de prueba anidada Use (Esto no es bueno para mezclar código de producción con código de prueba. Necesito mencionar de nuevo que soy un buen desarrollador y solo sigo las mejores prácticas)
- Use Java Reflection Use (Sí, esto parece interesante, estoy en ello)
A pesar de la creencia común de que en realidad es posible acceder a campos privados y métodos de otras clases a través de Java Reflection. Ni siquiera es tan difícil. Esto puede ser muy útil durante las pruebas unitarias.
Nota: Esto solo funciona cuando se ejecuta el código como una aplicación Java independiente, como se hace con las pruebas unitarias y las aplicaciones regulares. Si intenta hacer esto dentro de un Applet de Java, tendrá que jugar con el SecurityManager. Pero, como eso no es algo que deba hacer muy a menudo, hasta ahora se ha dejado fuera de este texto.
Se agregó soporte de reflexión de parámetros de método en Java 8. En pocas palabras, proporciona soporte para obtener los nombres de los parámetros en tiempo de ejecución.
para acceder A un campo privado deberá llamar a la etiqueta Class.getDeclaredField(String name)
o Class.getDeclaredFields()
método. Los métodos Class.getField(String name)
y Class.getFields()
solo devuelven campos públicos, por lo que no funcionarán. Aquí hay un ejemplo simple de una clase con un campo privado, y debajo de ese código para acceder a ese campo a través de reflexión 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);
Este ejemplo de código imprimirá el texto "fieldValue = The Private Value”
, que es el valor del campo privado privateString
del PrivateObject
la instancia creada al principio del ejemplo de código.
Observe el uso del método PrivateObject.class.getDeclaredField("privateString")
. Es esta llamada al método la que devuelve el campo privado. Este método solo devuelve los campos declarados en esa clase en particular, no los campos declarados en ninguna superclase.
Observe la línea en negrita también. Al llamar a Field.setAcessible(true)
desactiva las comprobaciones de acceso para esta instancia Field
, solo para reflexión. Ahora puede acceder a él incluso si es privado, protegido o de ámbito de paquete, incluso si la persona que llama no forma parte de esos ámbitos. Todavía no puede acceder al campo usando el código normal. El compilador no lo permitirá.
Acceso a métodos privados
Para acceder a un método privado, deberá llamar al método Class.getDeclaredMethod(String name, Class parameterTypes)
o Class.getDeclaredMethods()
. Los métodos Class.getMethod(String name, Class parameterTypes)
y Class.getMethods()
solo devuelven métodos públicos, por lo que no funcionarán.
Aquí hay un ejemplo simple de una clase con un método privado, y debajo de eso el código para acceder a ese método a través de Reflexión 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);
Este ejemplo de código imprimirá el texto "returnValue = The Private Value”
, que es el valor devuelto por el método getPrivateString()
cuando se invoca en PrivateObject
la instancia creada al principio del código muestra.
Observe el uso del método PrivateObject.class.getDeclaredMethod("privateString")
. Es esta llamada al método la que devuelve el método privado. Este método solo devuelve los métodos declarados en esa clase en particular, no los métodos declarados en ninguna superclase.
Observe la línea en negrita también. Al llamar a Method.setAcessible(true)
desactiva las comprobaciones de acceso para esta instancia Method
, solo para reflexión. Ahora puede acceder a él incluso si es privado, protegido o de ámbito de paquete, incluso si la persona que llama no forma parte de esos ámbitos. Todavía no puede acceder al método usando el código normal. El compilador no lo permitirá.
Probemos este conocimiento con código de nivel de producción.
Aquí está la clase que contiene algunos métodos privados que queremos probar.