Junit Nested Tests
Junit: Nested Tests
Las pruebas anotadas con @Nested ofrecen al desarrollador de pruebas más capacidades para expresar la relación entre varios grupos de pruebas. Estas pruebas anidadas aprovechan las clases anidadas de Java y facilitan una forma de pensar jerárquica sobre la estructura de las pruebas.
Este enfoque permite organizar las pruebas de forma más clara, especialmente cuando se desea agrupar pruebas relacionadas bajo un contexto común. Las clases anidadas pueden heredar configuraciones o datos del nivel superior, y pueden tener sus propios métodos @BeforeEach, @AfterEach, etc., específicos para ese grupo.
Nested test suite for testing a stack
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.EmptyStackException;
import java.util.Stack;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@DisplayName("A stack")
class TestingAStackDemo {
Stack<Object> stack;
@Test
@DisplayName("is instantiated with new Stack()")
void isInstantiatedWithNew() {
new Stack<>();
}
@Nested
@DisplayName("when new")
class WhenNew {
@BeforeEach
void createNewStack() {
stack = new Stack<>();
}
@Test
@DisplayName("is empty")
void isEmpty() {
assertTrue(stack.isEmpty());
}
@Test
@DisplayName("throws EmptyStackException when popped")
void throwsExceptionWhenPopped() {
assertThrows(EmptyStackException.class, stack::pop);
}
@Test
@DisplayName("throws EmptyStackException when peeked")
void throwsExceptionWhenPeeked() {
assertThrows(EmptyStackException.class, stack::peek);
}
@Nested
@DisplayName("after pushing an element")
class AfterPushing {
String anElement = "an element";
@BeforeEach
void pushAnElement() {
stack.push(anElement);
}
@Test
@DisplayName("it is no longer empty")
void isNotEmpty() {
assertFalse(stack.isEmpty());
}
@Test
@DisplayName("returns the element when popped and is empty")
void returnElementWhenPopped() {
assertEquals(anElement, stack.pop());
assertTrue(stack.isEmpty());
}
@Test
@DisplayName("returns the element when peeked but remains not empty")
void returnElementWhenPeeked() {
assertEquals(anElement, stack.peek());
assertFalse(stack.isEmpty());
}
}
}
}
Al ejecutar este ejemplo en un IDE, el árbol de ejecución de pruebas en la GUI tendrá un aspecto similar al de la siguiente imagen.

Executing a nested test in an IDE
En este ejemplo, las condiciones previas de las pruebas externas se utilizan en las pruebas internas mediante la definición de métodos de ciclo de vida jerárquicos para el código de configuración. Por ejemplo, createNewStack() es un método del ciclo de vida anotado con @BeforeEach, que se utiliza en la clase de prueba en la que se define y en todos los niveles del árbol de anidamiento por debajo de dicha clase.
El hecho de que el código de configuración de las pruebas externas se ejecute antes de que se ejecuten las pruebas internas te da la capacidad de ejecutar todas las pruebas de forma independiente. Incluso puedes ejecutar únicamente las pruebas internas sin necesidad de ejecutar las pruebas externas, ya que el código de configuración de las pruebas externas siempre se ejecuta.
Solo las clases anidadas no estáticas (es decir, clases internas) pueden servir como clases de prueba con la anotación
@Nested. La anidación puede tener cualquier profundidad, y esas clases internas están sujetas a un soporte completo del ciclo de vida, con una excepción: los métodos@BeforeAlly@AfterAllno funcionan por defecto.La razón es que Java no permite miembros estáticos en clases internas antes de Java 16. Sin embargo, esta restricción puede eludirse anotando una clase de prueba
@Nestedcon@TestInstance(Lifecycle.PER_CLASS)(ver Ciclo de Vida de la Instancia de Prueba).Si estás utilizando Java 16 o superior, los métodos
@BeforeAlly@AfterAllpueden declararse como estáticos dentro de clases de prueba@Nested, y esta restricción ya no aplica.