컬렉션 검증

List/Collection 전용 메서드

메서드 설명
isEmpty 빈 컬렉션인지 확인
isNotEmpty 비어있지 않은지 확인
hasSize 특정 크기인지 확인
hasSizeGreaterThan 특정 크기보다 큰지 확인
hasSizeLessThan 특정 크기보다 작은지 확인
hasSameSizeAs 다른 컬렉션과 같은 크기인지 확인
contains 특정 요소를 포함하는지 확인 (순서 무관)
containsOnly 지정한 요소만 포함하는지 확인 (순서 무관, 중복 허용)
containsExactly 순서와 원소가 정확히 일치하는지 확인
containsExactlyInAnyOrder 원소는 일치하나 순서는 무관
containsSequence 특정 순서로 연속된 요소가 있는지 확인
containsSubsequence 순서대로 포함 (중간에 다른 요소 허용)
doesNotContain 특정 요소를 포함하지 않는지 확인
startsWith 처음 요소들이 일치하는지 확인
endsWith 마지막 요소들이 일치하는지 확인
containsNull Null 요소를 포함하는지 확인
doesNotContainNull Null 요소를 포함하지 않는지 확인
containsAnyOf 지정한 요소 중 하나라도 포함하는지 확인
doesNotHaveDuplicates 중복 요소가 없는지 확인
allMatch 모든 요소가 조건을 만족하는지 확인
anyMatch 하나 이상의 요소가 조건을 만족하는지 확인
noneMatch 모든 요소가 조건을 만족하지 않는지 확인

코드 예제

@Test
void listBasicAssertions() {
    List<String> languages = Arrays.asList("Java", "Python", "JavaScript");
    
    // 크기 검증
    assertThat(languages)
        .isNotEmpty()
        .hasSize(3)
        .hasSizeGreaterThan(2)
        .hasSizeLessThan(5);
    
    // 포함 여부 검증
    assertThat(languages)
        .contains("Java", "Python")
        .doesNotContain("Ruby", "Go")
        .containsAnyOf("Java", "C++", "Rust");
}

@Test
void listOrderAssertions() {
    List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
    
    // 정확한 순서 검증
    assertThat(fruits)
        .containsExactly("Apple", "Banana", "Cherry")
        .startsWith("Apple")
        .endsWith("Cherry")
        .containsSequence("Banana", "Cherry");
    
    // 순서 무관 검증
    assertThat(fruits)
        .containsExactlyInAnyOrder("Cherry", "Apple", "Banana")
        .containsOnly("Banana", "Apple", "Cherry");
    
    // Subsequence 검증 (중간에 다른 요소 허용)
    assertThat(fruits)
        .containsSubsequence("Apple", "Cherry"); // Banana를 건너뛰어도 OK
}

@Test
void listNullAndDuplicates() {
    List<String> withNull = Arrays.asList("A", null, "B");
    List<String> withDuplicates = Arrays.asList("A", "B", "A");
    List<String> unique = Arrays.asList("A", "B", "C");
    
    // Null 검증
    assertThat(withNull).containsNull();
    assertThat(unique).doesNotContainNull();
    
    // 중복 검증
    assertThat(withDuplicates).containsOnly("A", "B");
    assertThat(unique).doesNotHaveDuplicates();
}

@Test
void listPredicateAssertions() {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    // Predicate를 사용한 검증
    assertThat(numbers)
        .allMatch(n -> n > 0)           // 모두 양수
        .anyMatch(n -> n % 2 == 0)      // 짝수가 하나 이상
        .noneMatch(n -> n > 10);        // 10보다 큰 수 없음
    
    List<String> words = Arrays.asList("hello", "world", "java");
    assertThat(words)
        .allMatch(s -> s.length() >= 4)
        .anyMatch(s -> s.contains("ll"))
        .noneMatch(String::isEmpty);
}

Map 검증

Map 전용 메서드

메서드 설명
isEmpty 빈 맵인지 확인
isNotEmpty 비어있지 않은지 확인
hasSize 특정 크기인지 확인
containsKey 특정 키를 포함하는지 확인
containsKeys 여러 키를 포함하는지 확인
doesNotContainKey 특정 키를 포함하지 않는지 확인
containsValue 특정 값을 포함하는지 확인
containsValues 여러 값을 포함하는지 확인
doesNotContainValue 특정 값을 포함하지 않는지 확인
containsEntry 특정 키-값 쌍을 포함하는지 확인
containsExactlyEntriesOf 다른 맵과 정확히 같은 엔트리를 가지는지 확인
containsOnlyKeys 지정한 키만 포함하는지 확인
containsAllEntriesOf 다른 맵의 모든 엔트리를 포함하는지 확인

코드 예제

@Test
void mapBasicAssertions() {
    Map<String, Integer> scores = new HashMap<>();
    scores.put("Alice", 95);
    scores.put("Bob", 87);
    scores.put("Charlie", 92);
    
    // 크기 검증
    assertThat(scores)
        .isNotEmpty()
        .hasSize(3);
    
    // 키 검증
    assertThat(scores)
        .containsKey("Alice")
        .containsKeys("Alice", "Bob")
        .doesNotContainKey("David")
        .containsOnlyKeys("Alice", "Bob", "Charlie");
    
    // 값 검증
    assertThat(scores)
        .containsValue(95)
        .containsValues(95, 87)
        .doesNotContainValue(100);
}

@Test
void mapEntryAssertions() {
    Map<String, String> user = new HashMap<>();
    user.put("name", "John");
    user.put("email", "john@example.com");
    user.put("role", "ADMIN");
    
    // 키-값 쌍 검증
    assertThat(user)
        .containsEntry("name", "John")
        .containsEntry("role", "ADMIN")
        .doesNotContainEntry("status", "ACTIVE");
    
    // 여러 엔트리 검증
    Map<String, String> expected = new HashMap<>();
    expected.put("name", "John");
    expected.put("email", "john@example.com");
    
    assertThat(user).containsAllEntriesOf(expected);
}

@Test
void mapComplexAssertions() {
    Map<String, Object> config = new HashMap<>();
    config.put("timeout", 3000);
    config.put("retryCount", 3);
    config.put("enabled", true);
    
    // 정확히 일치하는 맵 검증
    Map<String, Object> expectedConfig = new HashMap<>();
    expectedConfig.put("timeout", 3000);
    expectedConfig.put("retryCount", 3);
    expectedConfig.put("enabled", true);
    
    assertThat(config).containsExactlyEntriesOf(expectedConfig);
    
    // 특정 타입 값 검증
    assertThat(config)
        .extractingByKey("timeout", as(InstanceOfAssertFactories.INTEGER))
        .isEqualTo(3000);
    
    assertThat(config)
        .extractingByKey("enabled", as(InstanceOfAssertFactories.BOOLEAN))
        .isTrue();
}

Optional 검증

Optional 전용 메서드

메서드 설명
isPresent 값이 존재하는지 확인
isEmpty 값이 비어있는지 확인
hasValue 특정 값을 가지는지 확인
hasValueSatisfying 값이 조건을 만족하는지 확인
contains hasValue와 동일
containsInstanceOf 특정 타입의 값을 포함하는지 확인

코드 예제

@Test
void optionalAssertions() {
    Optional<String> present = Optional.of("Spring Boot");
    Optional<String> empty = Optional.empty();
    
    // 존재 여부 검증
    assertThat(present).isPresent();
    assertThat(empty).isEmpty();
    
    // 값 검증
    assertThat(present)
        .hasValue("Spring Boot")
        .contains("Spring Boot");
    
    // 조건부 검증
    assertThat(present)
        .hasValueSatisfying(value -> {
            assertThat(value).startsWith("Spring");
            assertThat(value).contains("Boot");
            assertThat(value).hasSize(11);
        });
}

@Test
void optionalWithObjects() {
    class User {
        private String name;
        private int age;
        
        User(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        public String getName() { return name; }
        public int getAge() { return age; }
    }
    
    Optional<User> userOpt = Optional.of(new User("John", 30));
    
    // 객체 필드 검증
    assertThat(userOpt)
        .isPresent()
        .hasValueSatisfying(user -> {
            assertThat(user.getName()).isEqualTo("John");
            assertThat(user.getAge()).isEqualTo(30);
        });
    
    // 타입 검증
    assertThat(userOpt).containsInstanceOf(User.class);
}

@Test
void optionalChaining() {
    Optional<String> email = Optional.of("test@example.com");
    
    // 메서드 체이닝
    assertThat(email)
        .isPresent()
        .hasValueSatisfying(e -> 
            assertThat(e)
                .contains("@")
                .endsWith(".com")
        );
}