[JAVA] assert 잘 사용하기 (with Spring Assert)

2024. 12. 11. 16:58·Java & Spring
목차
  1. 개요
  2. Java의 assert
  3. Enable Assertions
  4. Spring 테스트 코드
  5. Gradle 테스트
  6. IntelliJ 테스트
  7. Spring의 Assert
  8. Java의 assert vs Spring의 Assert
  9. 정리
  10. 마무리
반응형

개요

코드를 작성하다 보면 기본적으로 가정하고 있는 조건들이 있다.

그런 조건들은 알고리즘을 파악하거나 주석을 읽으면서 확인할 수 있지만,

Assertion을 사용하여 보다 명시적으로 나타낼 수 있다.

 

Java에서 기본적으로 제공하는 assert 문법을 알아보고,

이를 Spring에서는 어떻게 사용해야 하는지,

또한 Spring의 Assert 클래스와는 어떻게 다른지 알아보자.

 

Java의 assert

java의 assert 문법은 기본적으로 아래와 같이 사용한다.

// assert [조건식];
assert 1 == 2;

// assert [조건식] : [실패 메시지];
assert 1 == 2 : "유효성 검사에 실패했습니다.";

조건식 결과가 true이면 정상적인 흐름, false이면 잘못된 경우임을 나타낸다.

 

하지만, 조건식의 결과가 false라고 해서 예외가 발생하지는 않는다.

이를 확인하기 위해 다음 코드를 실행해 보자.

assert 1 == 2 : "유효성 검사에 실패했습니다.";
System.out.println("Success!");

아마도 우리가 예상하는 건, 1은 2와 같지 않기 때문에 실패 메시지가 나타는 것이다.

하지만 실행 결과는 아래와 같다.

실행 결과

실행 결과를 확인해 보면 assert 구문이 무시된 채로 "Success!"가 출력되고 있음을 알 수 있다.

 

기본적으로 assert 구문은 특정 상태를 가정하고 있다는 것을 명시적으로 나타내는 구문이기 때문에,

프로그램 내에서 유효성 검사를 직접 수행하지 않는다.

 

Enable Assertions

하지만 Java의 VM Option에 -ea를 추가하면 assert 구문으로 유효성 검사를 수행할 수 있다.

(ea : Enable Assertions의 약자)

 

IntelliJ에서는 아래와 같이 설정할 수 있다.

  1. Application 탭 누른 후 구성 편집 선택
  2. 옵션 수정 선택
  3. VM 옵션 추가 선택
  4. VM 옵션 입력 창에 -ea 입력

설정 후 다시 실행해 보면 아래와 같은 실행 결과가 나타난다.

실행 결과

Spring 테스트 코드

이제 Spring의 테스트 코드에서는 동일한 assert 구문이 어떻게 동작하는지 확인해 보자.

먼저 아래와 같이 테스트 코드를 작성하자.

class AssertTest {

    @Test
    void javaAssert() {
        assert 1 == 2 : "유효성 검사에 실패했습니다.";
    }
}

그러고 나서 테스트 코드를 실행해 보자.

실행 결과

테스트 코드에서는 -ea 설정을 별도로 추가해주지 않았음에도 assert 유효성 검사가 동작하는 것을 확인할 수 있다.

왜 테스트 코드에서만 유효성 검사가 동작하는지 각 테스트 환경을 기준으로 알아보자. (Gradle, IntelliJ IDEA)
(IntelliJ 설정 > 빌드, 실행, 배포 > 빌드 도구 > Gradle에서 "다음을 사용하여 테스트 실행" 설정값 확인)

 

Gradle 테스트

IntelliJ IDEA의 기본 테스트 환경은 Gradle이다.

이는 IDE가 없는 환경에서 빌드 혹은 테스트를 돌리는 환경과 동일하게 구성하기 위함일 것이다.

 

테스트 환경을 확인하기 위해 IntelliJ에서 테스트 실행 구성을 아래와 같이 수정해 보자.

  1. 테스트 실행 버튼 우클릭 후 실행 구성 수정 선택
  2. 실행 명령어 가장 뒤에 --info 추가

이후 다시 실행하면 아래와 같은 로그를 확인할 수 있다.

실행 결과

테스트 실행 시 자동으로 -ea 옵션을 추가하는 것을 확인할 수 있다.

 

테스트도 프로그램 실행 시처럼 -ea 없이 실행하고 싶으면 어떻게 해야 할 까?

아래 Gradle Test의 공식 문서를 참고해 보자.

https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html#org.gradle.api.tasks.testing.Test:enableAssertions

enableAssertions 속성이 기본적으로 true로 설정되어 있음을 알 수 있다.

이를 비활성화하기 위해 build.gradle에서 해당 속성을 false로 추가해 주자.

tasks.named('test') {
    useJUnitPlatform()
    enableAssertions = false // 기본값 : true
}

 

Gradle 동기화 후 다시 테스트를 돌려 보면 아래와 같이 성공함을 알 수 있다.

 

IntelliJ 테스트

IntelliJ 테스트는 실행 구성을 확인해 보면 자동으로 -ea가 삽입되어 있는 것을 확인할 수 있다.

따라서 위 속성을 제거하고 실행해 보면 테스트가 성공함을 확인할 수 있다.

 

Spring의 Assert

Spring에서는 Assert 클래스 및 수많은 메서드를 제공한다.

위 assert 예제와 동일한 형태로 예제 코드를 작성해 보자.

Assert.isTrue(1 == 2, "유효성 검사에 실패했습니다.");
System.out.println("Success!");

실행 결과는 아래와 같다.

실행 결과

-ea 등의 설정 없이도 바로 유효성 검사가 실패하는 모습을 확인할 수 있다.

내부 동작을 확인하기 위해 Assert 클래스의 해당 메서드를 찾아가 보자.

Assert.isTrue

내부 구현을 보면 단순히 표현식이 false이면 IllegalArgumentException을 throw하는 것을 확인할 수 있다.

따라서 설정에 관계 없이 항상 유효성 검사가 동작할 것임을 알 수 있다.

 

Java의 assert vs Spring의 Assert

위의 결과를 요약하면 아래와 같다.

  • Java의 assert
    • 기본적으로 프로그램 실행 시 로직 수행하지 않음, 테스트 코드 실행 시 기본적으로 로직 수행
    • 설정을 통해 실행 여부 변경 가능
    • 참 / 거짓에 대한 유효성 검사만 가능
    • 유효성 검사 실패 시 AssertionError throw
  • Spring의 Assert
    • 항상 로직 수행
    • 참 / 거짓 뿐만 아니라 다양한 경우의 유효성 검사 지원
    • 유효성 검사 실패 시 IllegalArgumentException throw

정리

따라서 이를 토대로 정리하면 아래와 같다.

 

Java의 assert는 기본적으로 프로그램 실행 시 무시되며,

유효성 검사 로직이 실행되었을 때 RuntimeException이 아닌 Error를 throw한다.

따라서 assert는 정확한 동작 검증 보다는 유효성에 대한 명세를 작성하기 위한 목적임을 알 수 있다.

(유효성 검사에 실패하더라도 다음 로직은 정상 수행되도록 구성해야 한다.)

 

반대로 Spring의 Assert는 항상 유효성 검사를 실행하며,

유효성 검사 로직이 실행되었을 때 RuntimeException을 호출한다.

따라서 실제로 운영 환경 내에서 유효성 검사를 실행하기 위한 목적임을 알 수 있다.

 

마무리

Assertion 관련하여 백기선님이 하셨던 말씀을 마지막으로 목적에 맞게 assert를 활용하기 위해 노력하자.

"어딘가에서 이미 검증을 했기 때문에 이 부분에서 이런 상황인 것을 가정하고 있다."
이런 것들을 표현하는 용도로는 주석보다는 assert 문을 활용하면 좋을 것 같다.

 

참고 자료

  • 인프런 코딩으로 학습하는 리팩토링 (백기선) > 리팩토링 43. 어서션 추가하기

 

모든 코드는 GitHub에서 확인하실 수 있습니다. :)

반응형

'Java & Spring' 카테고리의 다른 글

[항해플러스 세미나] 실무에서 유용한 Exception 처리  (0) 2025.01.17
[Spring] Spring Boot 1.x에서 JUnit5 사용하기  (1) 2024.10.11
[사내 세미나] Spring Batch 도입하기  (3) 2024.09.04
[Spring] 레거시 프로젝트에 Testcontainers 도입하기  (2) 2024.07.07
Spring Boot 무료로 배포하기 (Koyeb, GitHub)  (0) 2024.03.21
  1. 개요
  2. Java의 assert
  3. Enable Assertions
  4. Spring 테스트 코드
  5. Gradle 테스트
  6. IntelliJ 테스트
  7. Spring의 Assert
  8. Java의 assert vs Spring의 Assert
  9. 정리
  10. 마무리
'Java & Spring' 카테고리의 다른 글
  • [항해플러스 세미나] 실무에서 유용한 Exception 처리
  • [Spring] Spring Boot 1.x에서 JUnit5 사용하기
  • [사내 세미나] Spring Batch 도입하기
  • [Spring] 레거시 프로젝트에 Testcontainers 도입하기
hojun-dev
hojun-dev
개발과 함께하는 일상을 그리는 블로그입니다.
개발 일상개발과 함께하는 일상을 그리는 블로그입니다.
  • hojun-dev
    개발 일상
    hojun-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (69)
      • Java & Spring (15)
      • Kubernetes (17)
      • Javascript (2)
      • Linux (2)
      • Setting (16)
      • Work (4)
      • 일상 (10)
      • 항해플러스 (3)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
hojun-dev
[JAVA] assert 잘 사용하기 (with Spring Assert)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.