java unit-testing variables junit private

java - JUnit Probando variables privadas?



unit-testing private (7)

Se me asignó la tarea de probar unidades en una clase en la que nunca trabajé directamente con JUnit, y estoy estrictamente prohibido cambiar el código en el paquete. Por lo general, esto no es un problema, ya que la mayor parte de nuestras pruebas unitarias se realizan solo por funcionalidad y consistencia de entrada / salida, lo que se puede hacer simplemente ejecutando rutinas y verificando sus valores de retorno.

Sin embargo, ocasionalmente es necesario verificar una variable privada dentro de la clase o editar directamente una variable privada para verificar el comportamiento interno. ¿Hay alguna manera de obtener acceso a estos, ya sea a través de JUnit o de cualquier otra forma, con el fin de probar la unidad sin cambiar realmente el código en el paquete fuente original? Y si no, ¿cómo manejan los programadores este problema en el mundo real donde un probador de unidades puede no ser la misma persona que el codificador?


A pesar del peligro de afirmar lo obvio: con una prueba unitaria, quiere probar el comportamiento correcto del objeto, y esto se define en términos de su interfaz pública. No le interesa cómo el objeto logra esta tarea: este es un detalle de implementación y no es visible para el exterior. Esta es una de las razones por las que se inventó OO: los detalles de implementación están ocultos. Entonces no tiene sentido probar a miembros privados. Dijiste que necesitas una cobertura del 100%. Si hay un fragmento de código que no puede probarse utilizando la interfaz pública del objeto, entonces este fragmento de código en realidad nunca se llama y, por lo tanto, no se puede probar. Eliminarlo



En primer lugar, ahora se encuentra en una mala posición - teniendo la tarea de escribir pruebas para el código que no creó originalmente y sin ningún cambio - ¡pesadilla! Habla con tu jefe y explícalo, no es posible probar el código sin hacerlo "comprobable". Para que el código sea comprobable, por lo general haces algunos cambios importantes;

En cuanto a las variables privadas. En realidad, nunca debes hacer eso. Apuntar a probar variables privadas es la primera señal de que algo está mal con el diseño ahora. Las variables privadas son parte de la implementación, las pruebas deben enfocarse en el comportamiento más que en los detalles de implementación.

A veces, los campos privados se abren con algún getter. Lo hago intentando evitar tanto como sea posible (marque en los comentarios, como ''usado para probar'').

Como no tiene posibilidad de cambiar el código, no veo la posibilidad (me refiero a la posibilidad real, no como Reflection hacks, etc.) de verificar la variable privada.


No puedo decir si ha encontrado algún código de caso especial que requiere que pruebe contra campos privados. Pero en mi experiencia, nunca tienes que probar algo privado, siempre público. ¿Tal vez podría dar un ejemplo de algún código en el que deba probar en privado?


Si crea sus clases de prueba en una carpeta separada que luego agrega a su ruta de compilación,

Entonces podría hacer que la clase de prueba sea una clase interna de la clase bajo prueba al usar el paquete correctamente para establecer el espacio de nombres. Esto le da acceso a campos y métodos privados.

Pero no te olvides de eliminar la carpeta de la ruta de compilación para tu versión de lanzamiento.


Reflection por ejemplo:

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