JAVA

[Java] JUnit 테스트 코드 메서드 정리

배씌 2025. 3. 20. 13:18

테스트 어노테이션

1. 기본적인 테스트

  • @Test - 단위 테스트 실행
@Test
void testAddition() {
    int result = 2 + 3;
    Assertions.assertEquals(5, result);
}

 

해당 메서드가 테스트 실행 대상이 됨


2. 테스트 실행 전 / 후 설정

  • @BeforeEach - 각 테스트 실행 전에 실행
@BeforeEach
void setUp() {
    System.out.println("테스트 시작");
}

 

주로 테스트 데이터 초기화에 사용됨

 

  • @AfterEach - 각 테스트 실행 후에 실행
@AfterEach
void close() {
    System.out.println("테스트 종료");
}

 

주로 테스트 종료 후 자원 반환에 사용됨

 

  • @BeforeAll - 모든 테스트 전에 딱 한 번만 실행
@BeforeAll
static void beforeAllTests() {
    System.out.println("테스트 시작");
}

 

공통 설정할 때 유리

 

  • @AfterAll - 모든 테스트 후에 한 번만 실행
@AfterAll
static void afterAllTests() {
    System.out.println("테스트 종료");
}

 

자원 할당 해제나, DB 연결 해제 시 유용

 

어노테이션 정리

@Test 일반적인 단위 테스트 실행
@BeforeEach 각 테스트 실행 전에 실행
@AfterEach 각 테스트 실행 후에 실행
@BeforeAll 모든 테스트 실행 전에 한 번만 실행
@AfterAll 모든 테스트 실행 후에 한 번만 실행

Assertions 메서드

테스트 결과가 기댓값과 일치하는지 검증한다.

 

[ given/when/then 패턴 ]

요즘 단위 테스트는 거의 given-when-then 패턴으로 작성한다. 1개의 단위 테스트를 3단계로 나누어 표현하는데, 의미는 아래와 같다.

  • given(준비) : 데이터를 준비해놓고 -> 객체 or 변수 세팅
  • when(실행) : 함수를 실행한 뒤 -> 테스트할 메서드 실행 
  • then(검증) : 결과를 확인한다. -> Assertions 메서드로 검증

위 단계에서 Assertions 메서드는 검증 단계에 해당한다.


1. 기본 검증문

  • assertEquals(expected, actual) - 기대값과 실제값이 같은지 검증
@Test
void testAssertEquals() {
    int expected = 10;
    int actual = 5 + 5;
    Assertions.assertEquals(expected, actual);
}

 

두 값이 같으면 테스트 성공

 

  • assertNotEquals(expected, actual) - 기대값과 실제값이 다른지 검증
@Test
void testAssertNotEquals() {
    int expected = 10;
    int actual = 5 + 4;
    Assertions.assertNotEquals(expected, actual);
}

 

두 값이 다르면 테스트 성공

 

  • assertTrue(condition) - 조건이 true 인지 검증
@Test
void testAssertTrue() {
    Assertions.assertTrue(3 < 5);
}

 

조건이 true 면 테스트 성공

 

  • assertFalse(condition) - 조건이 false 인지 검증
@Test
void testAssertFalse() {
    Assertions.assertFalse(3 > 5);
}

 

조건이 false 면 성공


2. 객체 비교

  • assertSame(expected, actual) - 두 객체가 같은 객체인지 검증
@Test
void testAssertSame() {
    String s1 = new String("Hello");
    String s2 = s1;
    
    Assertions.assertSame(s1, s2);
}

 

두 객체가 같은 객체(같은 메모리 주소) 면 테스트 성공

 

  • assertNotSame(expected, actual) - 두 객체가 다른 객체인지 검증
@Test
void testAssertNotSame() {
    String s1 = new String("Hello");
    String s2 = new String("Hello");

    Assertions.assertNotSame(s1, s2);
}

 

두 객체가 다른 객체면 테스트 성공


3. Null 체크

  • assertNull(Object) - 객체가 null 인지 검증
@Test
void testAssertNull() {
    String str = null;
    
    Assertions.assertNull(str);
}

 

객체가 null 이면 테스트 성공

 

  • assertNotNull(Object) - 객체가 null이 아닌지 검증
@Test
void testAssertNotNull() {
    String str = "null";

    Assertions.assertNotNull(str);
}

 

객체가 null 이 아니면 테스트 성공


4. 예외 발생 테스트

  • assertThrows(Exception.class, 실행 코드) - 해당 예외가 발생하는지 검증
@Test
void testAssertThrows() {
    Assertions.assertThrows(ArithmeticException.class, () -> {
        int result = 10 / 0;
    });
}

 

특정 예외 발생하면 테스트 성공


5. 여러개 동시에 검증

  • assertAll(검증 1, 검증 2, ... )
@Test
void testAssertAll() {
    Assertions.assertAll(
            () -> Assertions.assertThrows(ArithmeticException.class, () -> {
                int result = 10 / 0;
            }),
            () -> Assertions.assertEquals(4, 2 * 2),
            () -> Assertions.assertTrue(5 > 3)
    );
}

 

모든 검증이 통과해야 테스트 성공


Mockito

개발자가 동작을 직접 제어할 수 있는 가짜 객체를 지원하는 테스트 프레임워크

 

[ Mockito 사용법 ]

1. Mock 객체 생성

  • @Mock, mock()
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;

class ProductServiceTest {

    @Mock // 가짜 객체 생성
    private ProductRepository productRepository;

    @InjectMocks // 가짜 객체를 주입받을 실제 객체
    private ProductService productService;

    @Test
    void testFindById() {
        MockitoAnnotations.openMocks(this); // Mockito 초기화

        // Mock 객체의 동작 설정
        Product mockProduct = new Product(1L, "Laptop", 1000);
        when(productRepository.findById(1L)).thenReturn(Optional.of(mockProduct));

        // 테스트 실행
        Product product = productService.getProduct(1L);

        // 검증
        assertEquals("Laptop", product.getName());
    }
}
  1. @Mock : ProductRepository 의 가짜 객체 생성
  2. @InjectMocks : ProductService 에 Mock 객체 (ProductRepository) 를 주입
  3. MockitoAnnotations.openMocks(this) : Mockito를 초기화
  4. when(...).thenReturn(...) : Mock 객체의 동작을 설정
    • productRepository.findById(1L)을 호출하면 Optional.of(mockProduct) 를 반환하도록
  5. assertEquals(...) : 결과 검증

2. Mock의 동작 설정

  • when().thenReturn()
when(객체.메서드()).thenReturn(반환값);

3. Mock 객체의 특정 메서드가 호출되었는지 검증

  • verify()
@Test
void testVerifyMethodCall() {
    productService.getProduct(1L);

    // productRepository.findById(1L) 메서드가 정확히 1번 호출되었는지 검증
    verify(productRepository, times(1)).findById(1L);
}

 


4. 예외 처리 테스트

  • doThrow()
@Test
void testExceptionHandling() {
    // productRepository.findById(2L) 호출 시 예외 발생하도록 설정
    when(productRepository.findById(2L)).thenThrow(new RuntimeException("Not Found"));

    assertThrows(RuntimeException.class, () -> {
        productService.getProduct(2L);
    });
}