Spring Framework/TDD / / 2024. 8. 7. 21:01

JUnit 5 - 강력한 테스트 검증을 위한 Assertions 활용법

Assertions

Assertions는 JUnit에서 테스트의 결과를 검증하기 위해 사용되는 중요한 도구입니다. Assertions는 테스트 메서드 내에서 특정 조건이 참인지 또는 거짓인지를 확인하고, 조건이 충족되지 않을 경우 테스트를 실패로 처리합니다. 이를 통해 코드가 예상대로 작동하는지 검증할 수 있습니다.

주요 Assertions 메서드

JUnit 5에서 제공하는 주요 Assertions 메서드와 그 역할을 설명하겠습니다.

  1. assertEquals(expected, actual):
    • 두 값이 서로 같은지 비교합니다.
    • 예를 들어, assertEquals(4, 2 + 2)는 2 + 2의 결과가 4와 같은지를 확인합니다.
    • 오버로드: assertEquals는 두 객체의 비교 외에도 부동 소수점 숫자의 비교를 위한 버전, 커스텀 메시지를 전달할 수 있는 버전 등 다양한 오버로드된 메서드를 제공합니다.
  2. assertNotEquals(unexpected, actual):
    • 두 값이 서로 같지 않은지 비교합니다.
    • 예를 들어, assertNotEquals(5, 2 + 2)는 2 + 2의 결과가 5와 같지 않음을 확인합니다.
  3. assertTrue(condition):
    • 조건이 참인지 확인합니다.
    • 예를 들어, assertTrue(5 > 3)는 5 > 3이 참인지를 확인합니다.
  4. assertFalse(condition):
    • 조건이 거짓인지 확인합니다.
    • 예를 들어, assertFalse(5 < 3)는 5 < 3이 거짓인지를 확인합니다.
  5. assertNull(object):
    • 객체가 null인지 확인합니다.
    • 예를 들어, assertNull(someObject)는 someObject가 null인지 확인합니다.
  6. assertNotNull(object):
    • 객체가 null이 아닌지 확인합니다.
    • 예를 들어, assertNotNull(someObject)는 someObject가 null이 아님을 확인합니다.
  7. assertArrayEquals(expectedArray, actualArray):
    • 두 배열의 내용이 같은지 비교합니다.
    • 예를 들어, assertArrayEquals(new int[]{1, 2, 3}, new int[]{1, 2, 3})는 두 배열이 동일한지 확인합니다.
  8. assertIterableEquals(expectedIterable, actualIterable):
    •  Iterable 객체의 요소들이 같은 순서로 동일한지 확인합니다.
    • 예를 들어, assertIterableEquals(List.of(1, 2, 3), List.of(1, 2, 3))는 두 리스트가 같은지 확인합니다.
  9. assertThrows(expectedType, executable):
    • 특정 예외가 발생하는지를 확인합니다.
    • 예를 들어, assertThrows(IllegalArgumentException.class, () -> methodThatShouldThrow())는 methodThatShouldThrow() 메서드가 IllegalArgumentException을 발생시키는지를 확인합니다.
  10. assertDoesNotThrow(executable):
    • 실행 중 예외가 발생하지 않는지를 확인합니다.
    • 예를 들어, assertDoesNotThrow(() -> methodThatShouldNotThrow())는 주어진 메서드가 예외를 발생시키지 않는지 확인합니다.
  11. assertTimeout(duration, executable):
    • 주어진 시간 내에 메서드가 완료되는지 확인합니다.
    • 예를 들어, assertTimeout(Duration.ofSeconds(1), () -> timeConsumingMethod())는 timeConsumingMethod()가 1초 이내에 완료되는지 확인합니다.
  12. assertAll(executables...):
    • 여러 개의 assertion을 동시에 검증할 수 있습니다. 하나의 실패가 다른 assertion의 검증을 중단하지 않습니다.
    • 예를 들어, assertAll("group of assertions", () -> assertTrue(1 < 2), () -> assertEquals(4, 2 + 2))는 여러 검증을 동시에 수행합니다.

예제 코드

아래는 JUnit 5를 사용한 Java 단위 테스트 코드입니다. 위에서 설명한 여러 assert 메서드를 포함한 테스트 케이스를 예시로 작성했습니다.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

import java.time.Duration;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class MyUnitTest {

    @Test
    void testAssertEquals() {
        int expected = 4;
        int actual = 2 + 2;
        assertEquals(expected, actual, "2 + 2 should equal 4");
    }

    @Test
    void testAssertNotEquals() {
        int unexpected = 5;
        int actual = 2 + 2;
        assertNotEquals(unexpected, actual, "2 + 2 should not equal 5");
    }

    @Test
    void testAssertTrue() {
        assertTrue(5 > 3, "5 is greater than 3");
    }

    @Test
    void testAssertFalse() {
        assertFalse(5 < 3, "5 is not less than 3");
    }

    @Test
    void testAssertNull() {
        Object someObject = null;
        assertNull(someObject, "Object should be null");
    }

    @Test
    void testAssertNotNull() {
        Object someObject = new Object();
        assertNotNull(someObject, "Object should not be null");
    }

    @Test
    void testAssertArrayEquals() {
        int[] expectedArray = {1, 2, 3};
        int[] actualArray = {1, 2, 3};
        assertArrayEquals(expectedArray, actualArray, "Arrays should be equal");
    }

    @Test
    void testAssertIterableEquals() {
        List<Integer> expectedList = List.of(1, 2, 3);
        List<Integer> actualList = List.of(1, 2, 3);
        assertIterableEquals(expectedList, actualList, "Iterables should be equal");
    }

    @Test
    void testAssertThrows() {
        Executable executable = () -> {
            throw new IllegalArgumentException("Invalid argument");
        };
        assertThrows(IllegalArgumentException.class, executable, "Should throw IllegalArgumentException");
    }

    @Test
    void testAssertDoesNotThrow() {
        Executable executable = () -> {
            // Do nothing (no exception should be thrown)
        };
        assertDoesNotThrow(executable, "Should not throw any exception");
    }

    @Test
    void testAssertTimeout() {
        Executable executable = () -> {
            // Simulate a task that takes less than 1 second
            Thread.sleep(500);
        };
        assertTimeout(Duration.ofSeconds(1), executable, "Should complete within 1 second");
    }

    @Test
    void testAssertAll() {
        assertAll("group of assertions",
            () -> assertTrue(1 < 2, "1 is less than 2"),
            () -> assertEquals(4, 2 + 2, "2 + 2 should equal 4"),
            () -> assertNotNull(new Object(), "Object should not be null")
        );
    }
}

코드 설명

  • testAssertEquals: 두 값이 같은지 확인하는 테스트입니다. assertEquals 메서드를 사용하여 expected와 actual이 같은지를 비교합니다.
  • testAssertNotEquals: 두 값이 같지 않은지 확인하는 테스트입니다. assertNotEquals 메서드를 사용하여 unexpected와 actual이 같지 않음을 확인합니다.
  • testAssertTrue: 조건이 참인지 확인하는 테스트입니다. assertTrue 메서드를 사용하여 5가 3보다 큰지를 확인합니다.
  • testAssertFalse: 조건이 거짓인지 확인하는 테스트입니다. assertFalse 메서드를 사용하여 5가 3보다 작은지를 확인합니다.
  • testAssertNull: 객체가 null인지 확인하는 테스트입니다. assertNull 메서드를 사용하여 someObject가 null임을 확인합니다.
  • testAssertNotNull: 객체가 null이 아닌지 확인하는 테스트입니다. assertNotNull 메서드를 사용하여 someObject가 null이 아님을 확인합니다.
  • testAssertArrayEquals: 두 배열이 같은지 확인하는 테스트입니다. assertArrayEquals 메서드를 사용하여 두 배열의 내용이 같은지 비교합니다.
  • testAssertIterableEquals: 두 Iterable 객체가 같은 순서로 동일한지 확인하는 테스트입니다. assertIterableEquals 메서드를 사용하여 두 리스트의 요소들이 동일한지 비교합니다.
  • testAssertThrows: 특정 예외가 발생하는지를 확인하는 테스트입니다. assertThrows 메서드를 사용하여 주어진 코드 블록이 IllegalArgumentException을 발생시키는지 확인합니다.
  • testAssertDoesNotThrow: 실행 중 예외가 발생하지 않는지를 확인하는 테스트입니다. assertDoesNotThrow 메서드를 사용하여 코드 블록이 예외를 발생시키지 않는지 확인합니다.
  • testAssertTimeout: 주어진 시간 내에 메서드가 완료되는지를 확인하는 테스트입니다. assertTimeout 메서드를 사용하여 주어진 코드 블록이 1초 이내에 완료되는지를 확인합니다.
  • testAssertAll: 여러 개의 assertion을 동시에 검증하는 테스트입니다. assertAll 메서드를 사용하여 한 번에 여러 검증을 수행합니다. 각 검증은 독립적으로 처리되며, 하나의 검증이 실패하더라도 나머지 검증이 계속 수행됩니다.

이 코드는 JUnit 5를 사용하여 다양한 종류의 단위 테스트를 작성하는 방법을 보여줍니다. 각 테스트 메서드는 독립적으로 실행될 수 있으며, 코드의 특정 동작을 검증하는 데 사용됩니다.

Custom Failure Messages

JUnit의 Assertions 메서드는 테스트 실패 시 표시될 커스텀 메시지를 추가로 받을 수 있습니다. 이는 테스트 결과가 실패할 경우, 왜 실패했는지를 명확하게 설명하는 메시지를 제공하는 데 유용합니다.

예를 들어:

assertEquals("The result should be 4", 4, 2 + 2);

위 예제에서, 만약 테스트가 실패한다면 "The result should be 4"라는 메시지가 출력됩니다.

Assertions의 중요성

Assertions는 테스트 코드에서 필수적인 요소로, 코드가 기대한 대로 동작하는지 검증하는 방법을 제공합니다. 잘 설계된 Assertions는 코드의 품질을 높이고, 버그를 초기에 발견하여 개발 비용을 줄이는 데 큰 도움이 됩니다. 또한, 커스텀 메시지를 통해 테스트 실패 시 원인을 신속하게 파악할 수 있게 도와줍니다.

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유