Tags:

Xác minh kết quả test case với Assertion trong JUnit 5

Assertion JUnit 5

Assertion trong JUnit 5 cung cấp các method hỗ trợ xác minh các mệnh đề bên trong các test case, được triển khai trong Assert class.

Chúng ta có các assertion method khác nhau phục vụ cho các trường hợp cụ thể.

assertArrayEquals

Method assertArrayEquals() dùng để xác mình rằng mảng dự kiến và mảng mong đợi bằng nhau.

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

    assertArrayEquals(expected, actual, "Arrays should be equal");
}

assertEquals và assertNotEquals

assertEquals() để xác minh giá trị mong đợi và giá trị thực tế bằng nhau. Trong khi assertNotEquals() dùng để xác minh 2 giá trị không giống nhau.

@Test
public void assertEqualsExample() {
    class test {
        int value;
        test(){}
        test(int value) {
            this.value = value;
        }
    }

    assertEquals(BigDecimal.valueOf(10), BigDecimal.valueOf(10)); // passed
    assertNotEquals(BigDecimal.valueOf(11), BigDecimal.valueOf(10)); // passed

    assertNotEquals(new test(), new test()); // passed
}

Chúng ta thấy đều là 2 object test khởi tạo như nhau nhưng chúng được assertNotEquals() xác nhận là không bằng nhau. Đó là vì trong quá trình xác minh assertNotEquals() sẽ gọi equals() method có sẵn trong Object class để so sánh 2 object, mặc định nó sẽ sánh vùng nhớ tất nhiên sẽ dẫn đến kết quả sai vì mỗi object khi được khởi tạo với từ khoá new sẽ được cấp một vùng nhớ riêng trong heap.

Chúng ta có thể triển khai như sau để có được kết quả kiểm thử như mong đợi.

@Test
    public void assertEqualsExample() {
        class test {
            int value;
            test(){}
            test(int value) {
                this.value = value;
            }

            @Override
            public boolean equals(Object obj) {
                return this.value == ((test) obj).value;
            }
        }

        assertEquals(BigDecimal.valueOf(10), BigDecimal.valueOf(10));
        assertNotEquals(BigDecimal.valueOf(11), BigDecimal.valueOf(10));

        assertEquals(new test(10), new test(10)); // passed
        assertNotEquals(new test(10), new test( 11)); //  passed

    }

assertTrue và assertFalse

assertTrue() dùng để xác minh điều kiện phải trả về true trong khi assertFalse() yêu cầu điều kiện kiểm thử phải là false.

@Test
public void assertTrueAndAssertFalseExample() {

    assertTrue(true);

    assertFalse(false);

    assertTrue(5 > 4, "5 is greater the 4");

    assertTrue(null == null, "null is equal to null");

    assertFalse(4 > 5, "5 is greater the 4" );


}

Chúng ta cũng có thể sử dụng biểu thức lambda expression với assertTrue()assertFalse().

@Test
public void assertTrueAndAssertFalseLambdaExample() {
    BooleanSupplier conditionTrue = () -> 5 > 4;

    BooleanSupplier conditionFalse = () -> 5 < 4;


    assertTrue(conditionTrue, "5 is greater the 4");

    assertFalse(conditionFalse, "5 is greater the 4");

}

assertNull và assertNotNull

Nếu chúng ta muốn kiểm tra một object không được null sử dụng assertNotNull() ngược lại sử dụng assertNull() nếu mong muốn một object là null trong test case.

@Test
public void whenAssertingNotNull_thenTrue() {
    Object dog = new Object();

    assertNotNull(dog, () -> "The dog should not be null");
}

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

assertSame and assertNotSame

Khi chúng ta muốn kiểm tra 2 object cùng tham chiếu đến một object trong vùng nhớ heap. 

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

fail

fail dùng để đánh dấu một test case chưa hoàn thiện, thường được sử dụng để đánh dấu các test cho những phần task đang trong quá trình phát triển.

@Test
public void failExample() {
    fail("FAIL - try to development");
}

assertAll

Một assertion mới được thêm trong JUnit 5, cho phép tạo một group các assertion với com assertion khác nhau như assertEquals, assertNull etc.

 @Test
    public void assertAllExample() {
        assertAll(
                "heading",
                () -> assertEquals(4, 2 * 2, "4 is 2 times 2"),
                () -> {
                    Integer value = 10;
                    assertNotNull(value);
                },
                () -> {
                    assertTrue(5 > 4, "5 must be greater 4");
                    assertFalse(4 > 5 , "5 must be greater 4");
                },
                () -> {
                    String origin = "str";
                    String s1 = origin;
                    String s2 = origin;
                    String s3 = "tmp";
                    assertSame(s1, s2);
                    assertNotSame(s1, s3);
                }
        );
    }

assertThrows

assertThrows() được dùng trong trường hợp chúng ta mong muốn quá trình thực thi của test case sẽ ném ra một exception.

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

assertTimeout và assertTimeoutPreemptively

assertTimeout()assertTimeoutPreemptively() đều được dùng để xác định khoảng thời gian chạy tối đa của test case. Điểm khác biệt duy nhất giữa chúng là với assertTimeoutPreemptively() quá trình thực thi của test case sẽ dừng lại khi hết thời gian được định, còn assertTimeout() thì không.

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

}

assertThorws và assertDoesNotThrow

assertThorw() được sử dụng để xác minh quá trình thực thi của test case sẽ xảy ra exception.

@Test
public void assertThrowsExample() {
    Exception exception = assertThrows(NumberFormatException.class, () -> {
        Integer.parseInt("1a");
    });
    String expectedMessage = "For input string";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

Nếu exception được ném ra trong test case thì assertThrows() sẽ trả về exception đó. Lưu ý mình sử dụng Exception là super class cho tất cả các exception để nhận kết quả trả về, nếu các bạn sử dụng các biến exception khác để bắt có thể gây lỗi vì các exception có kiểu khác nhau.

assertDoesNotThrows() dùng để xác minh quá trình thực thi test case không xảy ra bất kỳ một exception nào.

@Test
public void assertDoesNotThrowsExample() {
    assertDoesNotThrow(() -> {
        int a = 3 + 10;
        System.out.println(a);
    }, "No exception is throws");
}

Tóm lược

Trên đây là tổng hợp các assertion dùng để xác minh các kết quả của test case. Qua đó chúng ta thấy rằng JUnit 5 đã phát triển các tính năng mới hết sức mạnh mẽ, hỗ trợ nâng cấp từ các version cũ, vậy ngại gì mà không sử dụng JUnit 5 cho dư án của chúng ta nào!

Nếu các bạn gặp khó khăn trong quá trình thực nghiệm, có thể checkout source mình đã soạn sẵn tại github repository.

Nguồn tham khảo

https://www.baeldung.com/junit-assertions

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x