Tooling Intermedio

JUnit 6 adopta @NullMarked de JSpecify, haciendo explícitos los contratos de nulos en toda su API de aserciones.

✕ JUnit 5
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class UserServiceTest {

    // JUnit 5: no null contracts on the API
    // Can assertEquals() accept null? Check source...
    // Does fail(String) allow null message? Unknown.

    @Test
    void findUser_found() {
        // Is result nullable? API doesn't say
        User result = service.findById("u1");
        assertNotNull(result);
        assertEquals("Alice", result.name());
    }

    @Test
    void findUser_notFound() {
        // Hope this returns null, not throws...
        assertNull(service.findById("missing"));
    }
}
✓ JUnit 6
import org.junit.jupiter.api.Test;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import static org.junit.jupiter.api.Assertions.*;

@NullMarked  // all refs non-null unless @Nullable
class UserServiceTest {

    // JUnit 6 API is @NullMarked:
    // assertNull(@Nullable Object actual)
    // assertEquals(@Nullable Object, @Nullable Object)
    // fail(@Nullable String message)

    @Test
    void findUser_found() {
        // IDE warns: findById returns @Nullable User
        @Nullable User result = service.findById("u1");
        assertNotNull(result); // narrows type to non-null
        assertEquals("Alice", result.name()); // safe
    }

    @Test
    void findUser_notFound() {
        @Nullable User result = service.findById("missing");
        assertNull(result); // IDE confirms null expectation
    }
}
¿Ves un problema con este código? Cuéntanos.
📜

Contratos explícitos

@NullMarked en el módulo de JUnit 6 documenta la semántica de nulos directamente en la API — sin necesidad de leer el código fuente.

🛡️

Seguridad en compilación

Los IDEs y analizadores alertan cuando se pasa null donde se espera no nulo, detectando errores antes de ejecutar los tests.

🌐

Estándar del ecosistema

JSpecify es adoptado por Spring, Guava y otros — semántica de nulos consistente en toda tu pila.

Enfoque Antiguo
API sin anotar
Enfoque Moderno
API @NullMarked
Desde JDK
17
Dificultad
Intermedio
JUnit 6 con seguridad de nulos JSpecify
Disponible

Disponible desde JUnit 6.0 (octubre 2025, requiere Java 17+)

JUnit 5 se distribuyó sin anotaciones de nulabilidad estandarizadas, dejando a los desarrolladores adivinar si los parámetros de aserción o los valores de retorno podían ser null. JUnit 6 adopta JSpecify en todo su módulo: la anotación @NullMarked hace que todos los tipos sin anotar sean no nulos por defecto, y @Nullable marca las excepciones. La clase Assertions anota explícitamente parámetros como assertNull(@Nullable Object actual) y fail(@Nullable String message), para que los IDEs y analizadores estáticos como NullAway y Error Prone puedan detectar el mal uso de null en tiempo de compilación en lugar de en tiempo de ejecución.

Compartir 𝕏 🦋 in