JUnit là một framework dùng để viết Ụnit Test cho các project Java. Nó có 2 phiên bản phổ biến là JUnit 4 và JUnit 5 với phiên bản JUnit 5 dành cho các project Java sử dụng Java 8 trở đi. Trong bài viết này, mình sẽ giới thiệu với các bạn những điểm cơ bản mà các bạn cần phải biết về JUnit framework này để sử dụng nó viết Unit Test các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:
Ở phiên bản JUnit 4 thì chúng ta chỉ cần khai báo 1 JUnit dependency là được, ví dụ như:
1 2 3 4 5 6 |
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> |
nhưng từ phiên bản JUnit 5, JUnit chia thành 3 module là:
- JUnit platform
- JUnit Jupiter
- và JUnit Vintage
nên để sử dụng JUnit phiên bản mới nhất các bạn cần khai báo các dependencies như sau:
1 2 3 4 5 6 7 8 9 10 11 12 |
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.9.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <version>5.9.3</version> <scope>test</scope> </dependency> |
Sự khác nhau giữa các module này là:
- JUnit platform là thư viện core của JUnit, chịu trách nhiệm khởi chạy các Unit Test cases trên JVM. Nó cũng hỗ trợ các TestEngine API giúp chúng ta có thể phát triển các testing framework khác chạy trên JUnit platform.
- JUnit Jupiter cung cấp các API, annotation để chúng ta viết Unit Test.
- JUnit Vintage được sử dụng để hỗ trợ chạy các Unit Test được viết sử dụng version cũ 3 hoặc 4 của JUnit.
Để làm ví dụ, mình sẽ thêm mới một class Calculation với phương thức sum() để tính tổng 2 số, có nội dung như sau:
1 2 3 4 5 6 7 8 |
package com.huongdanjava.junit; public class Calculation { public int sum(int a, int b) { return a + b; } } |
Để viết Unit Test cho class Calculation, mình sẽ tạo mới một class tên là CalculationTest với package giống package chứa class Calculation nhưng trong thư mục src/test/java như sau:
Để thêm một Unit Test case để test phương thức sum() của class Calculation, chúng ta sẽ thêm mới một method và annotate method này với annotation @Test như sau:
1 2 3 4 5 6 7 8 9 10 11 |
package com.huongdanjava.junit; import org.junit.jupiter.api.Test; public class CalculationTest { @Test void testSum() { } } |
Các bạn có thể khởi tạo đối tượng Calculation sau đó gọi phương thức sum() để test phương thức sum() trong phương thức testSum() này như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.junit; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class CalculationTest { @Test void testSum() { Calculation calculation = new Calculation(); int result = calculation.sum(1,2); Assertions.assertEquals(3, result); } } |
Chúng ta sẽ sử dụng các phương thức assert…() có trong class Assertions để assert thông tin mà chúng ta muốn. Ở ví dụ trên, mình đang sử dụng phương thức assertEquals() để assert kết quả trả về của phương thức sum() đó các bạn!
Kết quả khi mình chạy test case này như sau:
Annotation @BeforeAll và @BeforeEach
Khi chạy Unit Test, các bạn sẽ có nhu cầu thực hiện một việc gì đó như khởi tạo đối tượng cho class, connect tới database, chuẩn bị data, … trước khi chạy các test cases. Để làm được điều này, các bạn có thể viết các method và annotate chúng với annotation @BeforeAll và @BeforeEach.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.huongdanjava.junit; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class CalculationTest { @BeforeAll static void doBeforeAll() { System.out.println("Do @BeforeAll"); } @BeforeEach void doBeforeEach() { System.out.println("Do @BeforeEach"); } @Test void testSum() { System.out.println("Do @Test"); Calculation calculation = new Calculation(); int result = calculation.sum(1,2); Assertions.assertEquals(3, result); } } |
@BeforeAll sẽ chạy trước tất cả các test case còn @BeforeEach sẽ chạy trước mỗi test case.
Kết quả:
Annotation @AfterAll và @AfterEach
Tương tự như @BeforeAll và @BeforeEach, chúng ta cũng có thêm các phương thức để làm một việc gì đó sau khi chạy mỗi test case và tất cả các test case với annotation @AfterAll và @AfterEach. Ví dụ như:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package com.huongdanjava.junit; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class CalculationTest { @BeforeAll static void doBeforeAll() { System.out.println("Do @BeforeAll"); } @BeforeEach void doBeforeEach() { System.out.println("Do @BeforeEach"); } @Test void testSum() { System.out.println("Do @Test"); Calculation calculation = new Calculation(); int result = calculation.sum(1,2); Assertions.assertEquals(3, result); } @AfterAll static void doAfterAll() { System.out.println("Do @AfterAll"); } @AfterEach void doAfterEach() { System.out.println("Do @AfterEach"); } } |
Kết quả:
Annotation @Disabled
Các bạn có thể disable một vài Unit Test case nào đó nếu muốn bằng cách sử dụng annotation @Disable, ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.huongdanjava.junit; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class CalculationTest { @BeforeAll static void doBeforeAll() { System.out.println("Do @BeforeAll"); } @BeforeEach void doBeforeEach() { System.out.println("Do @BeforeEach"); } @Test @Disabled void testSum() { System.out.println("Do @Test"); Calculation calculation = new Calculation(); int result = calculation.sum(1,2); Assertions.assertEquals(3, result); } @AfterAll static void doAfterAll() { System.out.println("Do @AfterAll"); } @AfterEach void doAfterEach() { System.out.println("Do @AfterEach"); } } |
Kết quả test case testSum() sẽ bị ignored khi chúng ta chạy Unit Test:
Annotation @DisplayName
Để thay đổi tên hiển thị của một test case hoặc của class Unit Test, các bạn có thể sử dụng annotation @DisplayName, ví dụ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package com.huongdanjava.junit; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @DisplayName("Calculation Test") public class CalculationTest { @BeforeAll static void doBeforeAll() { System.out.println("Do @BeforeAll"); } @BeforeEach void doBeforeEach() { System.out.println("Do @BeforeEach"); } @Test @DisplayName("Test Sum") void testSum() { System.out.println("Do @Test"); Calculation calculation = new Calculation(); int result = calculation.sum(1,2); Assertions.assertEquals(3, result); } @AfterAll static void doAfterAll() { System.out.println("Do @AfterAll"); } @AfterEach void doAfterEach() { System.out.println("Do @AfterEach"); } } |
Kết quả:
Đến đây thì mình đã giới thiệu với các bạn những kiến thức cơ bản, giúp các bạn có thể viết Unit Test cho các project Java sử dụng JUnit. Còn nhiều vấn đề liên quan, chúng ta sẽ cùng nhau tìm hiểu trong các bài viết tới các bạn nhé!