Java 단위 테스트 프레임워크인 Junit에서 코드에서 기대하는 조건을 확인하여 테스트의 결과를 판단하는 데 사용되는 요소이다. Assertions 메서드들을 사용하여 테스트 코드에서 예상한 값과 실제 값이 일치하는 지 테스트 결과를 평가하는 데 도움을 준다.
아래 메서드들은 Junit Assertions에서 주로 사용되는 메서드들이다.
assertEquals(expected, actual, msg)
AssertNotEquals(expected, actual, msg)
assertEquals("DevHwan@gmail.com", student.getEmailAddress(), "find by email address");
예상한 값과 실제 값이 일치하는 지 확인하는 메서드이다. 테스트가 실패했을 때, 지정한 메시지를 출력하도록 할 수 있다. Not의 경우는 그 반대이다.
assertSame(expected, actual)
assertNotSame(expected, actual)
예상한 객체와 실제 객체가 일치(주소)하는 지 확인하는 메서드이다. 테스트가 실패했을 때, 지정한 메시지를 출력하도록 할 수 있다.
같은 역할을 하는 것으로 보이는 두 메서드의 차이점이 무엇인가?? 본인은 테스트 코드를 작성하면서 해당 내용이 너무 궁금했다. 이전 글에 공식문서들을 하나씩 뜯어보면서 설명한 글이 있으니 참고해도 좋다.
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(condition, String message)
assertFalse(condition, String message)
assertTrue(studentService.checkIfStudentIsNull(1));
assertFalse(studentService.checkIfStudentIsNull(0));
주어진 조건이 참인지, 거짓인지 확인하는 지 확인하는 메서드이다. 테스트가 실패했을 때, 지정된 메시지를 출력하도록 할 수 있다.
<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");
예외처리에 대한 테스트 메서드와 시간초과에 대한 테스트 메서드가 있다.
assertTimeout
에서는 제한시간이 초과되더라도 계속 실행하고 테스트를 종료한다. assertTimeoutPreemptively
에서는 이전과 다르게 제한시간이 초과되면 계속 실행하지 않고 그 즉시 테스트를 종료한다.assertArrayEquals(Object[] expected, Object[] actual)
assertIterableEquals(Iterable<?> expected, Iterable<?> actual, String message)
assertLinesMatch(List<String> expectedLines, List<String> actualLines, String message)
유익한 자료 감사합니다.