¿Existe una anotación de prueba unitaria o un indicador de función que pueda insertar en mi código fuente de Java para que el método solo se active al ejecutar la prueba unitaria?

Por ejemplo:

public class A {        
    @Annotation
    public void fooA() { }

    public void fooB() { }
}

Clase de prueba de mi unidad:

public class TestA {
  ...
}

En este escenario, cuando ejecuto mi clase de prueba unitaria TestA, quiero ejecutar fooA () y fooB () .

Pero si quisiera ejecutar mi código fuente que incluye la clase A, entonces solo se ejecutará la función fooB () y no fooA () .

1
Red M 24 abr. 2017 a las 18:55

3 respuestas

La mejor respuesta

En general: no vayas allí.

Su código de producción tiene una responsabilidad; y una sola responsabilidad: hacer su trabajo de producción. No tiene en cuenta los aspectos complejos relacionados con las pruebas.

Ocasionalmente, puede ser necesario o útil tener un constructor que acepte más argumentos (para la inyección de dependencia). Luego, haga que ese paquete esté protegido y coloque un comentario informal "/ ** prueba unitaria solamente * /" allí.

Lo que quiero decir es: no existe tal anotación. Y tampoco tiene sentido tener uno. Describe su interfaz externa con javadoc claro, escribe sus clases para que sea obvio que un usuario solo debe usar / llamar fooB().

La cosa es: lo último que desea que suceda es que algún artefacto de solo prueba en su código cause un problema en su entorno de producción. Y la mejor manera de evitar ese riesgo: no cree tales artefactos.

2
GhostCat 25 abr. 2017 a las 02:24

¿Por qué un código que se usa solo para pruebas debería estar disponible en producción?

1) no valida el código aplicativo ya que la aplicación no lo usa.

2) Es propenso a errores para los clientes de la clase que lo usan.

3) Hace más difícil la mantenibilidad y la legibilidad del código.
Por ejemplo, un desarrollador podría preguntarse por qué este método está presente si no tiene un llamador en el código aplicativo. Al considerarlo como un código muerto, podría eliminar el método y eliminar también la prueba de la unidad que lo utiliza.

Para resolver su problema, creo que este método que se requiere en entornos no productivos debe incluirse en el paquete de la aplicación en entornos no productivos, pero debe excluirse del paquete en el entorno productivo.
Herramientas como Maven y Gradle manejan muy bien este requisito.

En realidad, no puede hacerlo ya que el método forma parte de una clase que se requiere en la producción. Entonces, un primer paso sería extraer el método para fines de prueba en una clase específica.
De esta manera, el filtrado sería posible.

0
davidxxx 24 abr. 2017 a las 19:03

Puede declarar que su paquete de prueba es el mismo que su unidad bajo prueba (UUT).

package com.example.fubar.arglebargle;
public class A {
   // package-private, TEST ONLY!
   void fooA() { }

   public void fooB() { }
}

Clase de prueba unitaria:

package com.example.fubar.arglebargle;
public class TestA {
    // etc...
}

Mi IDE hace esto automáticamente con las pruebas JUnit. Todas mis pruebas se declaran en el mismo paquete que mi UUT (aunque obviamente están en un árbol fuente completamente diferente; ¡no coloque las pruebas y la fuente de producción en el mismo subdirectorio!).

Esto es útil para acceder a algunas partes internas que de otro modo no estarían disponibles. También parece ser una práctica estándar, así que creo que no hay nada en contra de hacerlo.

Esto no impedirá que todos llamen a fooA(), pero limitará los posibles problemas a las clases en el mismo paquete que su clase. Es un conjunto de código mucho más pequeño del que preocuparse, y a menudo puede confiar en que las personas modifiquen el código para leer los comentarios en otras clases en el mismo paquete con cuidado.

Creo que algunos marcos de prueba pueden acceder a métodos privados (¿quizás deshabilitando el administrador de seguridad?) Pero no lo sé de inmediato. Si es importante, investigaría los marcos de prueba.

0
markspace 24 abr. 2017 a las 16:18