반응형

SwitchIfEmpty란?

 

switchIfEmpty() 메소드는 Mono나 Flux가 발행하는 값이 없을 때, 다른 Mono나 Flux를 대신 발행 할 수 있도록 하는 메소드이다.

즉, Mono나 Flux가 비어있을 때, 다른 Mono나 Flux를 반환하여 기본값이나 대체값을 제공할 수 있다.

 

 

Mono<User> userMono = userRepository.findById(id)
                .switchIfEmpty(Mono.error(new UserNotFoundException("User not found with id: " + id)));

위의 예시를 통해 알아보자.

 

예를 들어, 사용자 검색 API에서 ID가 id인 사용자를 찾을 때, 만약 해당 ID를 가진 사용자가 없다면 Mono.error()을 사용하여 UserNotFoundException 예외를 발생시킬 수 있다.

 

하지만, 이 예외가 발생하면 HTTP 응답으로 500 Internal Server Error가 반환되게 된다.

이를 방지하기 위해 switchIfEmpty() 메소드를 사용하여 Mono.error() .대신, Mono.empty()를 반환하도록 할 수 있고 Mono가 비어있다는 것을 나타내기 때문에 HTTP 응답으로 404 Not Found를 반환할 수 있다.

 

따라서, switchIfEmpty() 메소드는 Mono나 Flux에서 발행하는 값이 없을 때, 기본값이나 대체값을 반환할 수 있도록 하는 유용한 메소드다.

 

 

만약 swichIfEmpty를 안쓴다면?

 

switchIfEmpty()를 사용하지 않으면 Mono나 Flux가 비어있을 때, 기본값이나 대체값이 없는 상태로 반환된다.

이 경우, Mono나 Flux가 비어있다는 것을 나타내는 값, 즉 null 또는 빈 리스트 등이 반환될 수 있다.

 

예를 들어, findById() 메소드가 Mono<User>를 반환할 때, ID가 id인 사용자를 찾을 수 없는 경우, Mono<User>가 비어있게 되고, Mono<User>가 null을 반환하게 되면 NullPointerException이 발생할 수 있다.

 

따라서, switchIfEmpty()를 사용하여 Mono<User>가 비어있을 때, 대체값을 반환하도록 설정하는 것이 좋다.

 

아래의 switchIfEmpty()를 사용하지 않는 예제 코드를 확인해보자.

public Mono<User> getUserById(String id) {
    return userRepository.findById(id);
}

위의 코드에서는 findById() 메소드가 반환하는 Mono<User>를 그대로 반환한다.

이 경우, ID가 id인 사용자를 찾을 수 없는 경우, Mono<User>가 null을 반환하게 된다. 따라서, 이 코드에서는 switchIfEmpty()를 사용하여 Mono<User>가 비어있을 때, 대체값을 반환하도록 수정하는 것이 좋다.

 

 

Test 코드 예제

 

// switchIfEmpty() 메소드를 사용한 getUserById() 예제
public Mono<User> getUserById(String id) {
    return userRepository.findById(id)
            .switchIfEmpty(Mono.error(new UserNotFoundException("User not found with id: " + id)));
}

// switchIfEmpty() 메소드를 사용하지 않은 getUserById() 예제
public Mono<User> getUserById(String id) {
    return userRepository.findById(id);
}

// 테스트 코드
@Test
public void testGetUserByIdWithSwitchIfEmpty() {
    Mono<User> userMono = userService.getUserById("1");
    StepVerifier.create(userMono)
            .expectError(UserNotFoundException.class)
            .verify();
}

@Test
public void testGetUserByIdWithoutSwitchIfEmpty() {
    Mono<User> userMono = userService.getUserById("2");
    StepVerifier.create(userMono)
            .expectNextCount(0)
            .expectComplete()
            .verify();
}

위의 테스트 코드에서, 

testGetUserByIdWithSwitchIfEmpty()는 switchIfEmpty() 메소드를 사용한 getUserById() 메소드를 테스트하고, 

testGetUserByIdWithoutSwitchIfEmpty()는 switchIfEmpty() 메소드를 사용하지 않은 getUserById() 메소드를 테스트한다 

 

첫 번째 테스트에서는, getUserById() 메소드가 UserNotFoundException 예외를 발생시키도록 설정했기 때문에, 
Mono에서 예외를 발생시키는 것을 확인할 수 있다. 

 

두 번째 테스트에서는, getUserById() 메소드가 어떠한 대체값도 제공하지 않았기 때문에,
 Mono가 비어있음을 확인할 수 있다. 이 경우, Mono에서 값이 발행되지 않고, Mono가 완료(complete) 상태가 되어야 한다.

반응형