unitaria tutorial test suma prueba para hacer ejemplos descargar configuracion con como java junit

java - tutorial - ¿Cómo puedo averiguar si el código se ejecuta dentro de una prueba JUnit o no?



prueba unitaria con junit (10)

En mi código, necesito hacer ciertas correcciones solo cuando se ejecuta dentro de una prueba JUnit. ¿Cómo puedo averiguar si el código se ejecuta dentro de una prueba JUnit o no? ¿Hay algo como JUnit.isRunning () == verdadero?


¿Qué tal si compruebas si junit jar está en classpath?


Cuando se usa Spring, se puede definir un bean que contenga este valor.

En contexto de aplicación:

@Bean public boolean isRunningTests() { return false; }

En el contexto de la aplicación de prueba:

@Bean public boolean isRunningTests() { return true; }

Inyecte el valor en un componente de Spring:

@Resource private boolean isRunningTests; private void someMethod() { if (isRunningTests()) { ....


En primer lugar, esta probablemente no sea una buena idea. Debería probar la unidad del código de producción real, no un código ligeramente diferente.

Si realmente quieres hacer esto, podrías mirar la pila de registros, pero como de todos modos estás cambiando tu programa para esto, también podrías introducir un nuevo campo booleano estático es isUnitTesting en tu código y hacer que JUnit lo establezca en verdadero. Mantenlo simple.


La solución más corta (menos código) es tener un indicador global que se establece cuando las pruebas no se están ejecutando. Luego puede configurarlo una vez en su main() (o punto de entrada similar) en lugar de configurarlo repetidamente en los métodos de configuración de todas las clases de prueba. Esto funcionará siempre y cuando no haya otra forma de ingresar el código (no hay una alternativa main ).

La segunda solución más corta es escanear la pila de llamadas para el paquete junit como en la respuesta de Janning . Esto funcionará en la medida en que junit no se oculte detrás de otra biblioteca y un ejecutor.

La inyección de dependencia también funcionará, pero en este caso es simplemente una forma elegante de establecer lo que esencialmente es una bandera global.


Muchas personas en este hilo dicen que es una mala idea que el código se ejecute de forma ligeramente diferente mientras se está bajo JUnit. Generalmente estoy de acuerdo, pero creo que hay algunas excepciones.

Por ejemplo, actualmente estoy escribiendo pruebas de INTEGRACIÓN (en lugar de unidades) para una aplicación que se conecta a un DB.

Estas pruebas de aceptación a menudo necesitan reiniciar completamente el DB con datos de prueba específicos.

Obviamente, no quiero que esto se HAGA NUNCA en un DB de producción real, porque eso podría borrar por completo datos de producción valiosos.

La forma más fácil de garantizar que esto nunca ocurra es imposibilitar que el código se conecte a un DB de producción cuando se ejecuta bajo JUnit. Esto a su vez puede hacerse si, por ejemplo, la fábrica que genera una conexión puede decir que se está ejecutando bajo JUnit, y en ese caso, devolverá una conexión nula a menos que la base de datos a la que estamos intentando conectar tenga un nombre conocido. ser una base de datos de prueba (por ejemplo, "testdatabase").


Para distinguir entre prueba y no prueba, siempre puede definir propiedades o valores especiales en application-test.properties.


Puede ser una buena idea si quiere decidir programáticamente qué "perfil" ejecutar. Piense en Spring Profiles para la configuración. Dentro de las pruebas de integración es posible que desee probar contra una base de datos diferente.

Aquí está el código probado que funciona

public static boolean isJUnitTest() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); List<StackTraceElement> list = Arrays.asList(stackTrace); for (StackTraceElement element : list) { if (element.getClassName().startsWith("org.junit.")) { return true; } } return false; }


Puedo encontrar una justificación para esto, que es cuando desea proporcionar el código en una clase de producción para ayudar a las pruebas. Esto sería similar a la afirmación de Java, que solo se aplica cuando se establece el indicador de depuración.

Algo como esto:

Object debugState() { // This is only meant to be called when testing if (!JUnit.isRunning()) { throw new IllegalStateException("Not in a test!"); } // Now compute possibly costly debug information // not to be used in production Object state = ... }


Si estás haciendo las cosas de manera diferente porque estás haciendo una prueba unitaria, estás derrotando el propósito de una prueba unitaria. Se supone que una prueba unitaria debe funcionar exactamente como lo haría la producción (excepto para la configuración y el desmontaje de cualquier información necesaria y tal que usted necesite ... pero eso está incluido en la prueba JUnit en sí misma y no en su código).

Sin embargo, si realmente tienes una buena razón para esto, miraría la pila y vería si JUnit está allí.


esto no está estrictamente relacionado con la pregunta del usuario, pero estoy bastante seguro de que alguien que llegue puede encontrarlo útil.

Utilizo el siguiente enfoque: exponer un constructor local del paquete que se utilizará en las pruebas.

p.ej

src / main / java / ApplicationService.java

public class ApplicationService { private final Integer someInternalObject; public ApplicationService(String somePublicArgument) throws NumberFormatException { someInternalObject = Integer.valueOf(somePublicArgument, 16); } ApplicationService(Integer someInternalObject) { this.someInternalObject = someInternalObject; } }

src / test / ApplicationServiceTest.Java

public class ApplicationServiceTest { @Test public void testSomething() throws Exception { ApplicationService applicationService = new ApplicationService(0); } }

exponerlo a todas las pruebas

no clases finales

Extiéndalo en las pruebas y proporcione un constructor público para el paquete local o protegido.

clases finales

Cree un Método de fábrica público en el mismo paquete (dentro de las pruebas) que lo creará utilizando el constructor local del paquete.