[TDD] Junit Assertions

DevHwan·2023년 8월 14일
0
post-thumbnail

Junit Assertions

Java 단위 테스트 프레임워크인 Junit에서 코드에서 기대하는 조건을 확인하여 테스트의 결과를 판단하는 데 사용되는 요소이다. Assertions 메서드들을 사용하여 테스트 코드에서 예상한 값과 실제 값이 일치하는 지 테스트 결과를 평가하는 데 도움을 준다.

아래 메서드들은 Junit Assertions에서 주로 사용되는 메서드들이다.

assertEquals, assertNotEquals

  • assertEquals(expected, actual, msg)
  • AssertNotEquals(expected, actual, msg)
assertEquals("DevHwan@gmail.com", student.getEmailAddress(), "find by email address");

예상한 값과 실제 값이 일치하는 지 확인하는 메서드이다. 테스트가 실패했을 때, 지정한 메시지를 출력하도록 할 수 있다. Not의 경우는 그 반대이다.

assertSame, assertNotSame

  • assertSame(expected, actual)
  • assertNotSame(expected, actual)

예상한 객체와 실제 객체가 일치(주소)하는 지 확인하는 메서드이다. 테스트가 실패했을 때, 지정한 메시지를 출력하도록 할 수 있다.

assertSame vs assertEquals

같은 역할을 하는 것으로 보이는 두 메서드의 차이점이 무엇인가?? 본인은 테스트 코드를 작성하면서 해당 내용이 너무 궁금했다. 이전 글에 공식문서들을 하나씩 뜯어보면서 설명한 글이 있으니 참고해도 좋다.

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;

public class AssertionExample {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");
        String str3 = str1;

        assertEquals(str1, str2); // 내용이 같으므로 통과
        assertSame(str1, str2);    // 서로 다른 객체이므로 실패

        assertSame(str1, str3);    // 같은 객체를 참조하므로 통과
    }
}

Java에서 기본적으로 제공하는 String 객체의 경우에는 다음과 같은 결과를 맞이한다. 본질적으로는 assertEquals 는 값을 비교, assertSame 은 주소를 비교하는 메서드로 보는 거 올바르다. 실제로 위의 예제도 동일하게 진행되는 것으로 보인다.

그렇지만 아래 예제에서는 클래스 내부 변수가 모두 같은 객체임에도 불구하고 테스트가 실패하는 것을 볼 수 있다.

@Test
    void test2() {
        TestClass testClass1 = new TestClass(1, 2);
        TestClass testClass2 = new TestClass(1, 2);

        assertEquals(testClass1, testClass2,"맞왜틀?");
        assertNotSame(testClass1, testClass2);
    }

    static class TestClass {
        int x;
        int y;

        public TestClass(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

그렇다. 기본적으로 역할은 위에서 말한 것과 같지만 Equals 메서드가 오버라이딩 되지 않는 경우에는 단순히 주소를 비교하여 확인한다. → 동일성 비교가 된다. 그렇기 때문에 해당 메서드의 동작 방식을 정확하게 이해하고 테스트 코드를 작성하는 것이 중요할 것이다.

  • 동일성 : 주어진 객체들이 동일한 객체인 지 확인한다.
  • 동등성 : 주어진 객체들이 가지고 있는 값이 같은 지 확인한다.

assertTrue, assertFalse

  • assertTrue(condition, String message)
  • assertFalse(condition, String message)
assertTrue(studentService.checkIfStudentIsNull(1));
assertFalse(studentService.checkIfStudentIsNull(0));

주어진 조건이 참인지, 거짓인지 확인하는 지 확인하는 메서드이다. 테스트가 실패했을 때, 지정된 메시지를 출력하도록 할 수 있다.

assertThrows, assertTimeout, assertTimeoutPreemptively

  • <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, String message)
  • <T> T assertDoesNotThrow(ThrowingSupplier<T> supplier, String message)
  • assertTimeout(Duration timeout, Executable executable, String message)
  • assertTimeoutPreemptively(Duration timeout, Executable executable, String message)
assertThrows(Exception.class, () -> demoUtils.throwException(-1), "a is less than 0");
assertDoesNotThrow(() -> demoUtils.throwException(1), "a is greater than 0");
assertTimeoutPreemptively(java.time.Duration.ofMillis(2222), () -> demoUtils.checkTimeout(), "checkTimeout should be done in 1000ms");

예외처리에 대한 테스트 메서드와 시간초과에 대한 테스트 메서드가 있다.

  • 주어준 수행문에 대하여 예상하는 예외 클래스가 발생하여 Throws 되는 지에 대하여 테스트 하는 것이다. 수행문은 Lambda 식을 통해서 주어진다.
  • 실행문이 제한시간안에 수행되는 지 확인하는 테스트이다. assertTimeout에서는 제한시간이 초과되더라도 계속 실행하고 테스트를 종료한다. assertTimeoutPreemptively에서는 이전과 다르게 제한시간이 초과되면 계속 실행하지 않고 그 즉시 테스트를 종료한다.

Others

  • assertArrayEquals(Object[] expected, Object[] actual)
    • 주어진 두 배열 일치하는 지 확인, 값 순서 길이 등
  • assertIterableEquals(Iterable<?> expected, Iterable<?> actual, String message)
    • 두 Iterable 객체 일치 확인
  • assertLinesMatch(List<String> expectedLines, List<String> actualLines, String message)
    • 문자열 비교에 사용한다.
profile
달리기 시작한 치타

1개의 댓글

comment-user-thumbnail
2023년 8월 14일

유익한 자료 감사합니다.

답글 달기