Mục lục
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() và 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() và 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