Tooling Średniozaawansowany

JUnit 6 przyjmuje JSpecify @NullMarked, czyniąc kontrakty null jawnymi w całym API asercji.

✕ 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
    }
}
Widzisz problem z tym kodem? Daj nam znać.
📜

Jawne kontrakty

@NullMarked w module JUnit 6 dokumentuje semantykę null bezpośrednio w API.

🛡️

Bezpieczeństwo w czasie kompilacji

IDE i analizatory ostrzegają gdy null jest przekazywany tam gdzie oczekiwany jest non-null.

🌐

Standard ekosystemu

JSpecify jest przyjęty przez Spring, Guava i innych — spójna semantyka null w całym stosie.

Stare podejście
API bez adnotacji null
Nowoczesne podejście
API @NullMarked
Od JDK
17
Poziom trudności
Średniozaawansowany
JUnit 6 z bezpieczeństwem null JSpecify
Dostępne

Dostępne od JUnit 6.0 (październik 2025, wymaga Java 17+)

JUnit 5 dostarczono bez standaryzowanych adnotacji nullable, zmuszając programistów do zgadywania czy parametry asercji lub wartości zwracane mogą być null. JUnit 6 przyjmuje JSpecify w całym swoim module — adnotacja @NullMarked czyni wszystkie nieadnotowane typy domyślnie non-null, a @Nullable oznacza wyjątki. Klasa Assertions jawnie adnotuje parametry jak assertNull(@Nullable Object actual), więc IDE i analizatory statyczne jak NullAway i Error Prone mogą wykrywać błędy null w czasie kompilacji.