¿Cómo funciona Junit @Rule?

195

Quiero escribir casos de prueba para una gran cantidad de código, me gustaría conocer los detalles de la @Rulefunción de anotación JUnit , para poder usarlo para escribir casos de prueba. Proporcione algunas buenas respuestas o enlaces, que brinden una descripción detallada de su funcionalidad a través de un ejemplo simple.

Dipak
fuente
Ya
he visitado
Encontré que este artículo explica @Rulebastante bien, especialmente echa un vistazo a la última sección "La secuencia de eventos en detalle"
Peter Perháč
Creo que es similar al concepto de inyección, ¿estoy en lo cierto?
Chao
Gracias por compartir ese enlace. Una cosa no está clara. ¿Cuándo se llama a DEFAULT Statement.evaluate ()? ¿Se llama antes de la evaluación () de todas las reglas o después de todas ellas? Estoy adivinando después de todos ellos.
MasterJoe2
@ testerjoe2 puede optar por ignorar por completo la declaración predeterminada. Puede elegir delegarle o simplemente reemplazarlo por completo con alguna otra Declaración propia. No consigo llamado , que puede llamar o no. Eso fue en el punto 10: "El método de evaluación de la declaración de captura de pantalla llama al método de evaluación de la declaración predeterminada".
Peter Perháč

Respuestas:

155

Las reglas se utilizan para agregar funcionalidad adicional que se aplica a todas las pruebas dentro de una clase de prueba, pero de una manera más genérica.

Por ejemplo, ExternalResource ejecuta código antes y después de un método de prueba, sin tener que usar @Beforey @After. Usar un en ExternalResourcelugar de @Beforey @Afterda oportunidades para una mejor reutilización del código; Se puede usar la misma regla de dos clases de prueba diferentes.

El diseño se basó en: interceptores en JUnit

Para obtener más información, consulte JUnit wiki: Reglas .

Matthew Farwell
fuente
1
Corrección: "Por ejemplo, ExternalResource ejecuta código antes y después de una clase de prueba ". Hay algo sobre el uso de apply () para hacer que ExternalResource se ejecute entre pruebas.
derekm
62

Las reglas de Junit funcionan según el principio de AOP (programación orientada a aspectos). Intercepta el método de prueba, lo que brinda la oportunidad de hacer algunas cosas antes o después de la ejecución de un método de prueba en particular.

Tome el ejemplo del siguiente código:

public class JunitRuleTest {

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  @Test
  public void testRule() throws IOException {
    File newFolder = tempFolder.newFolder("Temp Folder");
    assertTrue(newFolder.exists());
  }
} 

Cada vez que se ejecuta el método de prueba anterior, se crea una carpeta temporal y se elimina después de la ejecución del método. Este es un ejemplo de una regla lista para usar proporcionada por Junit.

También se puede lograr un comportamiento similar creando nuestras propias reglas. Junit proporciona la interfaz TestRule, que se puede implementar para crear nuestra propia regla Junit.

Aquí hay un enlace útil para referencia:

Abhishek Mohanty
fuente
44
para que se elimine sin escribir ningún código para eliminar / borrar el objeto?
Dror
mire la fuente de github.com/junit-team/junit4/blob/master/src/main/java/org/… , la carpeta se crea en el método de devolución de llamada before () y se elimina en el método de devolución de llamada after (). ..
Pierluigi Vernetto
1
Para las personas que podrían no haber entendido por qué el TemporaryFolder se elimina, es porque es un TemporaryFolder proporcionado por Junit para servir como una carpeta temporal que se elimina automáticamente, es decir, el paso de desmontaje es parte de la clase TemporaryFolder.
Mindaugas Bernatavičius
17

tl; dr por cómo funciona: JUnit envuelve su método de prueba en un objeto de declaración, por lo que la declaración. Execute () ejecuta su prueba. Luego, en lugar de llamar a la instrucción. Execute () directamente para ejecutar su prueba, JUnit pasa la instrucción a un TestRule con la anotación @Rule. La función "aplicar" de TestRule devuelve una nueva Declaración dada la Declaración con su prueba. El nuevo método Execute () de la instrucción puede llamar al método de ejecución de la instrucción de prueba (o no, o llamarlo varias veces) y hacer lo que quiera antes y después. Ahora JUnit tiene una nueva instrucción que hace más que simplemente ejecutar la prueba, y puede pasarla nuevamente a otras reglas antes de finalmente llamar a Ejecutar.

Alexander Taylor
fuente
2
La declaración tiene el método evaluar no ejecutar.
Hemanth
0

Las reglas se utilizan para mejorar el comportamiento de cada método de prueba de forma genérica. La regla Junit intercepta el método de prueba y nos permite hacer algo antes de que un método de prueba comience la ejecución y después de que se haya ejecutado un método de prueba.

Por ejemplo, usando la regla @Timeout podemos establecer el tiempo de espera para todas las pruebas.

public class TestApp {
    @Rule
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS);

    ......
    ......

 }

La regla @TemporaryFolder se usa para crear carpetas temporales, archivos. Cada vez que se ejecuta el método de prueba, se crea una carpeta temporal y se elimina después de la ejecución del método.

public class TempFolderTest {

 @Rule
 public TemporaryFolder tempFolder= new TemporaryFolder();

 @Test
 public void testTempFolder() throws IOException {
  File folder = tempFolder.newFolder("demos");
  File file = tempFolder.newFile("Hello.txt");

  assertEquals(folder.getName(), "demos");
  assertEquals(file.getName(), "Hello.txt");

 }


}

Puede ver ejemplos de algunas reglas integradas proporcionadas por junit en este enlace .

Hari Krishna
fuente