JUnit 4 및 JUnit 5의 어설 션

1. 소개

이 기사에서는 JUnit에서 사용할 수있는 어설 션에 대해 자세히 살펴 보겠습니다.

JUnit 4에서 JUnit 5 로의 마이그레이션과 JUnit 5 가이드 문서에 이어 JUnit 4와 JUnit 5에서 사용할 수있는 다양한 어설 션에 대해 자세히 살펴 보겠습니다.

또한 JUnit 5의 어설 션에 대한 개선 사항을 강조 할 것입니다.

2. 주장

어설 션은 테스트에서 어설 션 조건을 지원하는 유틸리티 메서드입니다 . 이러한 메소드는 JUnit 4 의 Assert 클래스와 JUnit 5 의 Assertions 클래스를 통해 액세스 할 수 있습니다 .

테스트 및 어설 션 자체의 가독성을 높이려면 항상 해당 클래스를 정적으로 가져 오는 것이 좋습니다 . 이런 식으로 표현 클래스를 접두사로 사용하지 않고 assertion 메서드 자체를 직접 참조 할 수 있습니다.

JUnit 4에서 사용할 수있는 어설 션을 살펴 보겠습니다.

3. JUnit 4의 어설 션

이 버전의 라이브러리에서 어설 션은 모든 기본 유형, 개체배열 (기본 또는 개체)에 사용할 수 있습니다.

어설 션 내에서 매개 변수 순서는 실제 값이 뒤 따르는 예상 값입니다. 선택적으로 첫 번째 매개 변수는 평가 된 조건의 메시지 출력을 나타내는 문자열 메시지 일 수 있습니다 .

assertThat 어설 션을 정의하는 방법에는 약간 다른 것이 있지만 나중에 다룰 것입니다.

assertEquals 1 부터 시작하겠습니다 .

3.1. assertEquals

assertEquals의 주장을 검증은 예상과 실제 값은 동일하다고 :

@Test public void whenAssertingEquality_thenEqual() { String expected = "Baeldung"; String actual = "Baeldung"; assertEquals(expected, actual); }

어설 션이 실패 할 때 표시 할 메시지를 지정할 수도 있습니다.

assertEquals("failure - strings are not equal", expected, actual);

3.2. assertArrayEquals

두 배열이 동일하다고 주장하려면 assertArrayEquals를 사용할 수 있습니다 .

@Test public void whenAssertingArraysEquality_thenEqual() { char[] expected = {'J','u','n','i','t'}; char[] actual = "Junit".toCharArray(); assertArrayEquals(expected, actual); }

두 배열이 모두 null 인 경우 어설 션은 두 배열이 동일한 것으로 간주합니다.

@Test public void givenNullArrays_whenAssertingArraysEquality_thenEqual() { int[] expected = null; int[] actual = null; assertArrayEquals(expected, actual); }

3.3. assertNotNullassertNull

객체가 null 인지 테스트 하려면 assertNull assertion을 사용할 수 있습니다 .

@Test public void whenAssertingNull_thenTrue() { Object car = null; assertNull("The car should be null", car); }

반대로 객체가 null이 아니어야한다고 주장 하려면 assertNotNull 주장을 사용할 수 있습니다 .

3.4. assertNotSameassertSame

assertNotSame ,이 두 변수가 같은 객체를 참조하지 않는 경우 확인 가능합니다 :

@Test public void whenAssertingNotSameObject_thenDifferent() { Object cat = new Object(); Object dog = new Object(); assertNotSame(cat, dog); }

그렇지 않으면 두 변수가 동일한 객체를 참조하는지 확인하려는 경우 assertSame 어설 션을 사용할 수 있습니다 .

3.5. assertTrueassertFalse

특정 조건이 true 또는 false 인지 확인하려는 경우 assertTrue 주장 또는 assertFalse 하나를 각각 사용할 수 있습니다 .

@Test public void whenAssertingConditions_thenVerified() { assertTrue("5 is greater then 4", 5 > 4); assertFalse("5 is not greater then 6", 5 > 6); }

3.6. 불합격

실패 주장이 던지는 테스트에 실패 AssertionFailedError을을 . 실제 예외가 발생했는지 확인하거나 개발 중에 테스트가 실패하도록 할 때 사용할 수 있습니다.

첫 번째 시나리오에서 어떻게 사용할 수 있는지 살펴 보겠습니다.

@Test public void whenCheckingExceptionMessage_thenEqual() { try { methodThatShouldThrowException(); fail("Exception not thrown"); } catch (UnsupportedOperationException e) { assertEquals("Operation Not Supported", e.getMessage()); } }

3.7. 주장

assertThat의 주장은 다른 주장 비교 파라미터의 역순을 갖는다 JUnit을 4 단 하나이다.

이 경우 어설 션에는 선택적 실패 메시지, 실제 값 및 Matcher 개체가 있습니다.

이 어설 션을 사용하여 배열에 특정 값이 포함되어 있는지 확인하는 방법을 살펴 보겠습니다.

@Test public void testAssertThatHasItems() { assertThat( Arrays.asList("Java", "Kotlin", "Scala"), hasItems("Java", "Kotlin")); } 

Matcher 개체를 사용한 assertThat assertion 의 강력한 사용에 대한 추가 정보 는 Testing with Hamcrest에서 확인할 수 있습니다.

4. JUnit 5 어설 션

JUnit 5는 JUnit 4의 많은 어설 션 메소드를 유지하면서 Java 8 지원을 활용하는 몇 가지 새로운 메소드를 추가했습니다.

또한이 버전의 라이브러리에서는 모든 기본 유형, 객체 및 배열 (기본 또는 객체)에 대해 어설 션을 사용할 수 있습니다 .

The order of the parameters of the assertions changed, moving the output message parameter as the last parameter. Thanks to the support of Java 8, the output message can be a Supplier, allowing lazy evaluation of it.

Let's start reviewing the assertions available also in JUnit 4.

4.1. assertArrayEquals

The assertArrayEquals assertion verifies that the expected and the actual arrays are equals:

@Test public void whenAssertingArraysEquality_thenEqual() { char[] expected = { 'J', 'u', 'p', 'i', 't', 'e', 'r' }; char[] actual = "Jupiter".toCharArray(); assertArrayEquals(expected, actual, "Arrays should be equal"); }

If the arrays aren't equal, the message “Arrays should be equal” will be displayed as output.

4.2. assertEquals

In case we want to assert that two floats are equals, we can use the simple assertEquals assertion:

@Test public void whenAssertingEquality_thenEqual() { float square = 2 * 2; float rectangle = 2 * 2; assertEquals(square, rectangle); }

However, if we want to assert that the actual value differs by a predefined delta from the expected value, we can still use the assertEquals but we have to pass the delta value as the third parameter:

@Test public void whenAssertingEqualityWithDelta_thenEqual() { float square = 2 * 2; float rectangle = 3 * 2; float delta = 2; assertEquals(square, rectangle, delta); }

4.3. assertTrue and assertFalse

With the assertTrue assertion, it's possible to verify the supplied conditions are true:

@Test public void whenAssertingConditions_thenVerified() { assertTrue(5 > 4, "5 is greater the 4"); assertTrue(null == null, "null is equal to null"); }

Thanks to the support of the lambda expression, it's possible to supply a BooleanSupplier to the assertion instead of a boolean condition.

Let's see how we can assert the correctness of a BooleanSupplier using the assertFalse assertion:

@Test public void givenBooleanSupplier_whenAssertingCondition_thenVerified() { BooleanSupplier condition = () -> 5 > 6; assertFalse(condition, "5 is not greater then 6"); }

4.4. assertNull and assertNotNull

When we want to assert that an object is not null we can use the assertNotNull assertion:

@Test public void whenAssertingNotNull_thenTrue() { Object dog = new Object(); assertNotNull(dog, () -> "The dog should not be null"); }

In the opposite way, we can use the assertNull assertion to check if the actual is null:

@Test public void whenAssertingNull_thenTrue() { Object cat = null; assertNull(cat, () -> "The cat should be null"); }

In both cases, the failure message will be retrieved in a lazy way since it's a Supplier.

4.5. assertSame and assertNotSame

When we want to assert that the expected and the actual refer to the same Object, we must use the assertSame assertion:

@Test public void whenAssertingSameObject_thenSuccessfull() { String language = "Java"; Optional optional = Optional.of(language); assertSame(language, optional.get()); }

In the opposite way, we can use the assertNotSame one.

4.6. fail

The fail assertion fails a test with the provided failure message as well as the underlying cause. This can be useful to mark a test when it's development it's not completed:

@Test public void whenFailingATest_thenFailed() { // Test not completed fail("FAIL - test not completed"); }

4.7. assertAll

One of the new assertion introduced in JUnit 5 is assertAll.

This assertion allows the creation of grouped assertions, where all the assertions are executed and their failures are reported together. In details, this assertion accepts a heading, that will be included in the message string for the MultipleFailureError, and a Stream of Executable.

Let's define a grouped assertion:

@Test public void givenMultipleAssertion_whenAssertingAll_thenOK() { assertAll( "heading", () -> assertEquals(4, 2 * 2, "4 is 2 times 2"), () -> assertEquals("java", "JAVA".toLowerCase()), () -> assertEquals(null, null, "null is equal to null") ); }

The execution of a grouped assertion is interrupted only when one of the executables throws a blacklisted exception (OutOfMemoryError for example).

4.8. assertIterableEquals

The assertIterableEquals asserts that the expected and the actual iterables are deeply equal.

In order to be equal, both iterable must return equal elements in the same order and it isn't required that the two iterables are of the same type in order to be equal.

With this consideration, let's see how we can assert that two lists of different types (LinkedList and ArrayList for example) are equal:

@Test public void givenTwoLists_whenAssertingIterables_thenEquals() { Iterable al = new ArrayList(asList("Java", "Junit", "Test")); Iterable ll = new LinkedList(asList("Java", "Junit", "Test")); assertIterableEquals(al, ll); }

In the same way of the assertArrayEquals, if both iterables are null, they are considered equal.

4.9. assertLinesMatch

The assertLinesMatch asserts that the expected list of String matches the actual list.

This method differs from the assertEquals and assertIterableEquals since, for each pair of expected and actual lines, it performs this algorithm:

  1. check if the expected line is equal to the actual one. If yes it continues with the next pair
  2. treat the expected line as a regular expression and performs a check with the String.matches() method. If yes it continues with the next pair
  3. check if the expected line is a fast-forward marker. If yes apply fast-forward and repeat the algorithm from the step 1

Let's see how we can use this assertion to assert that two lists of String have matching lines:

@Test public void whenAssertingEqualityListOfStrings_thenEqual() { List expected = asList("Java", "\\d+", "JUnit"); List actual = asList("Java", "11", "JUnit"); assertLinesMatch(expected, actual); }

4.10. assertNotEquals

Complementary to the assertEquals, the assertNotEquals assertion asserts that the expected and the actual values aren't equal:

@Test public void whenAssertingEquality_thenNotEqual() { Integer value = 5; // result of an algorithm assertNotEquals(0, value, "The result cannot be 0"); }

If both are null, the assertion fails.

4.11. assertThrows

In order to increase simplicity and readability, the new assertThrows assertion allows us a clear and a simple way to assert if an executable throws the specified exception type.

Let's see how we can assert a thrown exception:

@Test void whenAssertingException_thenThrown() { Throwable exception = assertThrows( IllegalArgumentException.class, () -> { throw new IllegalArgumentException("Exception message"); } ); assertEquals("Exception message", exception.getMessage()); }

The assertion will fail if no exception is thrown, or if an exception of a different type is thrown.

4.12. assertTimeout and assertTimeoutPreemptively

In case we want to assert that the execution of a supplied Executable ends before a given Timeout, we can use the assertTimeout assertion:

@Test public void whenAssertingTimeout_thenNotExceeded() { assertTimeout( ofSeconds(2), () -> { // code that requires less then 2 minutes to execute Thread.sleep(1000); } ); }

However, with the assertTimeout assertion, the supplied executable will be executed in the same thread of the calling code. Consequently, execution of the supplier won't be preemptively aborted if the timeout is exceeded.

In case we want to be sure that execution of the executable will be aborted once it exceeds the timeout, we can use the assertTimeoutPreemptively assertion.

두 주장은 대신에, 받아 들일 수 있습니다 실행, ThrowingSupplier 객체와 그 반환 잠재적으로 던질 수있는 코드의 일반적인 블록 대표 의 Throwable를.

5. 결론

이 튜토리얼에서는 JUnit 4와 JUnit 5에서 사용 가능한 모든 어설 션을 다뤘습니다.

우리는 새로운 주장의 도입과 람다의 지원과 함께 JUnit 5의 개선 사항을 간략하게 강조했습니다.

항상 그렇듯이이 기사의 전체 소스 코드는 GitHub에서 사용할 수 있습니다.