Tooling Intermediário

O JUnit 6 adota @NullMarked do JSpecify, tornando os contratos de nulidade explícitos em toda a API de asserções.

✕ 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
    }
}
Viu um problema com este código? Nos avise.
📜

Contratos explícitos

@NullMarked no módulo do JUnit 6 documenta a semântica de null diretamente na API — sem necessidade de ler o código-fonte.

🛡️

Segurança em tempo de compilação

IDEs e analisadores alertam quando null é passado onde non-null é esperado, detectando bugs antes dos testes rodarem.

🌐

Padrão do ecossistema

O JSpecify é adotado pelo Spring, Guava e outros — semântica de null consistente em toda a sua stack.

Abordagem Antiga
API sem anotações
Abordagem Moderna
API @NullMarked
Desde o JDK
17
Dificuldade
Intermediário
JUnit 6 com null safety do JSpecify
Disponível

Disponível desde o JUnit 6.0 (outubro de 2025, requer Java 17+)

O JUnit 5 foi lançado sem anotações de nulidade padronizadas, deixando os desenvolvedores adivinhando se parâmetros de asserção ou valores de retorno poderiam ser nulos. O JUnit 6 adota o JSpecify em todo o seu módulo — a anotação @NullMarked torna todos os tipos não anotados non-null por padrão, e @Nullable marca as exceções. A classe Assertions anota explicitamente parâmetros como assertNull(@Nullable Object actual) e fail(@Nullable String message), para que IDEs e analisadores estáticos como NullAway e Error Prone detectem uso incorreto de null em tempo de compilação em vez de em tempo de execução.

Compartilhar 𝕏 🦋 in