JUnit5 검증 - Assertion

Assertion 값 검증 메소드 설명, AssertJ에 대한 간단한 설명

Assertion

JUnit5는 Assertions 라는 단언문 클래스를 제공한다.
Assertion(단언문)은 제공되는 메소드를 사용해서 테스트에서 검증하고자하는 값이나 동작을 확인하는 기능을 한다.

값 검증 Assertion

기본적인 단언문 메소드가 준비되어 있다.

assertEquals

assertEquals(expect, actual, {message})는 실제 값(actual)이 기대한 값(expect)과 같은지 확인한다.

package com.devkuma.junit5.assertion;

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

import org.junit.jupiter.api.Test;

public class AssertEqualsTest {

    @Test
    void basicTest() {
        assertEquals(1, 2);
    }

    @Test
    void numberTest() {
        assertEquals(1, 2, "숫자 비교");
    }

    @Test
    void stringTest() {
        assertEquals("abc", "ABC", "문자 비교");
    }
}

실행 결과:

expected: <1> but was: <2>
Expected :1
Actual   :2

숫자 비교 ==> expected: <1> but was: <2>
Expected :1
Actual   :2

문자 비교 ==> expected: <abc> but was: <ABC>
Expected :abc
Actual   :ABC

assertNull(actual)

assertNull(actual, {message})는 값이 null인지 확인한다.

package com.devkuma.junit5.assertion;

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

import org.junit.jupiter.api.Test;

public class AssertNullTest {

    @Test
    void fail() {
        String name = null;

        assertNull(name, "name is null");
    }

    @Test
    void success() {
        String name = "kimkc";

        assertNull(name, "name is null");
    }
}

assertNotNull(actual)

assertNotNull(actual, {message})는 값이 null이 아닌지 확인한다.

package com.devkuma.junit5.assertion;

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

import org.junit.jupiter.api.Test;

public class AssertNotNullTest {

    @Test
    void fail() {
        String name = null;

        assertNotNull(name, "name is not null");
    }

    @Test
    void success() {
        String name = "kimkc";

        assertNotNull(name, "name is not null");
    }
}

assertTrue(boolean),

assertTrue(actual, {message})는 다음 조건이 참(true)인지 확인한다.

package com.devkuma.junit5.assertion;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

public class AssertTrueTest {

    @Test
    void trueTest() {
        boolean a = true;

        assertTrue(a);
    }

    @Test
    void arithmeticTrue() {
        int a = 3;
        int b = 10;

        assertTrue(a > b, "a가 b보다 커야 한다.");
    }
}

assertFalse(boolean)

assertFalse(actual, {message})는 다음 조건이 참(false)인지 확인한다.

package com.devkuma.junit5.assertion;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

public class AssertFalseTest {

    @Test
    void falseTest() {
        boolean a = true;

        assertFalse(a);
    }

    @Test
    void arithmeticFalse() {
        int a = 3;
        int b = 10;

        assertFalse(a > b, "a가 b보다 커지 말아야 한다.");
    }
}

편리한 Assertion

값 검증을 위한 메소드 외에도, 편리한 메소드도 준비되어 있다.

assertAll(executable…)

assertAll(executable...)은 모든 테스트를 한번에 실행할 수 있다.

아래와 같이 여러개의 단언문을 사용할때, 앞에 테스트가 실패하게 되면 다음 테스트는 실행되지 않는다. 그러기 때문에 다음 테스트가 실패했는 지 알 수 없다.

@Test
void basicTest() {
    String name = null;

    assertNotNull(name, "name is not null");
    assertEquals(1, 2);
}

이럴때 assertAll 메소드를 사용하면, 전체 테스트의 결과를 전부 확인할 수 있다.

@Test
void allTest() {
    final String name = null;

    assertAll(
            () -> assertNotNull(name, "name is not null"),
            () -> assertEquals(1, 2)
    );
}

전체 코드는 아래와 같다.

package com.devkuma.junit5.assertion;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.Test;

public class AssertAllTest {
    
    @Test
    void basicTest() {
        String name = null;

        assertNotNull(name, "name is not null");
        assertEquals(1, 2);
    }

    @Test
    void allTest() {
        final String name = null;

        assertAll(
                () -> assertNotNull(name, "name is not null"),
                () -> assertEquals(1, 2)
        );
    }
}

assertThrows(expectedType, executable)

assertThrows는 예외 발생하는지에 대해서 확인할 수 있다. 발생한 예외의 메세지가 동일한지도 할 수도 있다.

package com.devkuma.junit5.assertion;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class AssertThrowsTest {

    void setNumber(int number) {
        if (number < 0) {
            throw new IllegalArgumentException("number must be greater than 0.");
        }
    }

    @Test
    void test() {
        IllegalArgumentException exception = assertThrows(
                IllegalArgumentException.class,
                () -> setNumber(-5)
        );
        String message = exception.getMessage();
        assertEquals("number must be greater than 0.", message);
    }
}

assertTimeout(duration, executable)

assertTimeout(duration, executable)은 특정 시간 안에 실행이 완료되는지 확인한다.

두번째 매개변수의 람다식이 종료되면 테스트가 같이 종료된다.

package com.devkuma.junit5.assertion;

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

import java.time.Duration;

import org.junit.jupiter.api.Test;

public class AssertTimeoutTest {

    @Test
    void timeoutTest() {
        assertTimeout(Duration.ofMillis(100), () -> {
            Thread.sleep(300);
        });
    }
}
  • 위 테스트 1초 안에 실행되는 것을 테스트를 하는 건데, 3초기 넘어 실패하게 된다.

assertTimeoutPreemptively(duration, executable)

assertTimeoutPreemptively는 특정 시간 안에 실행이 완료되는지 확인한다.

assertTimeout와의 차이점은 assertTimeout는 지정한 시간까지 기다렸다고 종료되지만, assertTimeoutPreemptively는 지정한 시간이 지나면 테스트가 바료 종료된다.

package com.devkuma.junit5.assertion;

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

import java.time.Duration;

import org.junit.jupiter.api.Test;

public class AssertTimeoutPreemptivelyTest {

    @Test
    void timeoutTest() {
        assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
            Thread.sleep(300);
        });
    }
}

다른 Assertion 라이브러리

JUnit5는 모든 다른 단언문 라이브러리를 사용할 수도 있다. AssertJ, Hamcrest 등을 의존 라이브러리에 추가하면, JUnit4 때와 같이 어렵지 않게 사용할 수 있다.

AssertJ

메소드 체이닝을 지원하기 때문에 좀 더 깔끔하고 읽기 쉬운 테스트 코드를 작성할 수 있다.

AssertJ를 종속성 라이브러리는 따로 추가해야 한다.
build.gradle

dependencies {
    // ... 
    testImplementation 'org.assertj:assertj-core:3.23.1'
}

AssertJ를 사용한 예제는 다음과 같다.

package com.devkuma.junit5.assertion;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class AssertjTest {

    @Test
    void numberTest() throws Exception {
        assertThat(10) // 주어진 10 숫자는
                .isZero() // 0이고,
                .isNotZero() // 0이 아니고,
                .isPositive() // 양수 이고,
                .isEqualTo(8); // 8과 일치한다.
    }

    @Test
    void stringTest() {
        assertThat("Hello, world! Nice to meet you.") // 주어진 "Hello, world! Nice to meet you." 문자열은
                .isNotEmpty() // 비어있지 않고
                .contains("Nice") // "Nice"를 포함하고
                .contains("world") // "world"도 포함하고
                .doesNotContain("ZZZ") // "ZZZ"는 포함하지 않으며
                .startsWith("Hell") // "Hell"로 시작하고
                .endsWith("u.") // "u."로 끝나며
                .isEqualTo("Hello, world! Nice to meet you."); // "Hello, world! Nice to meet you."과 일치한다.
    }

}



최종 수정 : 2024-04-14