JUnit Kiểm tra ngoại lệ dự kiến: @Test(expected)
⚡ Tóm tắt thông minh
JUnit Kiểm thử ngoại lệ xác nhận rằng một phương thức ném ra lỗi mà nó được cho là sẽ ném ra, bằng cách sử dụng tham số expected tùy chọn của chú thích @Test trong JUnit 4 và phương thức assertThrows trong JUnit 5.
JUnit cung cấp cơ sở vật chất cho tracxử lý ngoại lệ và kiểm tra xem mã có ném ra ngoại lệ dự kiến hay không.
JUnit Mục 4 cung cấp một cách dễ dàng và dễ đọc để kiểm thử ngoại lệ. Bạn có thể sử dụng:
- Tham số tùy chọn (được mong đợi) của Chú thích @Testvà
- Đến tracVới thông tin này, có thể sử dụng hàm “fail()”.
Trong khi thử nghiệm Nếu là trường hợp ngoại lệ, bạn cần đảm bảo rằng lớp ngoại lệ mà bạn cung cấp trong tham số tùy chọn đó là đúng. Chú thích @Test Đây chính là ngoại lệ mà phương thức thực sự ném ra. Điều này là do bạn đang mong đợi một ngoại lệ từ phương thức mà bạn đang... kiểm tra đơn vị; nếu không thì của chúng ta JUnit thử nghiệm sẽ thất bại.
Ví dụ: @Test(expected = IllegalArgumentException.class)
Bằng cách sử dụng tham số “expected”, bạn có thể chỉ định tên ngoại lệ mà bài kiểm tra của chúng ta có thể ném ra. Trong ví dụ trên, bạn đang sử dụng “Ngoại lệ Đối số bất hợp pháp"Lỗi này sẽ được báo cáo trong bài kiểm tra nếu nhà phát triển sử dụng một đối số không được phép."
Ví dụ sử dụng @Test(expected)
Hãy cùng tìm hiểu về kiểm thử ngoại lệ bằng cách tạo ra một ví dụ. Java lớp có một phương thức ném ra một ngoại lệ ngoại lệBạn sẽ xử lý và kiểm tra nó trong một lớp kiểm thử. Hãy xem xét JUnitTệp Message.java có một phương thức thực hiện phép toán. Phép chia ở dòng 14 chia cho 0, vì vậy phương thức luôn ném ra ngoại lệ “ArithmeticException”. Xem bên dưới:
package guru99.junit; public class JUnitMessage{ private String message; public JUnitMessage(String message) { this.message = message; } public void printMessage(){ System.out.println(message); int divide=1/0; } public String printHiMessage(){ message="Hi!" + message; System.out.println(message); return message; } }
Code Giải thích:
- Code Dòng 7: Tạo một hàm tạo được tham số hóa với việc khởi tạo trường.
- Code Dòng 11-14: Xây dựng phương pháp cho phép toán.
- Code Dòng 18: Tạo một phương pháp khác để in tin nhắn.
- Code Dòng 20: Tạo một chuỗi mới để in một tin nhắn.
- Code Dòng 22: In thông báo mới được tạo ở dòng 20.
Chúng ta hãy tạo một lớp kiểm thử cho đoạn mã trên. Java lớp để xác minh ngoại lệ.
Xem bên dưới lớp kiểm thử thực hiện kiểm thử đơn vị ngoại lệ (ở đây là ArithmeticException) được ném ra từ đoạn mã trên. Java lớp học:
AirthematicTest.java
Ảnh chụp màn hình bên dưới hiển thị cùng một bài kiểm tra trong trình chỉnh sửa, trong đó tệp được lưu dưới dạng AirthematicTest1, với tham số mong đợi được đánh dấu ở dòng 13:
package guru99.junit; import static org.junit.Assert.assertEquals; import org.junit.Test; public class AirthematicTest { public String message = "Saurabh"; JUnitMessage junitMessage = new JUnitMessage(message); @Test(expected = ArithmeticException.class) public void testJUnitMessage(){ System.out.println("Junit Message is printing "); junitMessage.printMessage(); } @Test public void testJUnitHiMessage(){ message="Hi!" + message; System.out.println("Junit Message is printing "); assertEquals(message, junitMessage.printHiMessage()); } }
Code Giải thích:
- Code Dòng 13: Sử dụng chú thích `@Test` để tạo bài kiểm tra. Khi bạn thực thi phương thức của lớp ở trên, nó sẽ gọi một phép toán. Ở đây, ngoại lệ `ArithmeticException` được mong đợi, vì vậy bạn liệt kê nó ra như một tham số trong `@Test`.
- Code Dòng 17: Gọi hàm printMessage() từ JUnitTin nhắn.java.
- Code Dòng 21-22: Tạo thêm một phương thức kiểm thử khác để kiểm tra thông báo "Hi", lần này không có tham số mong đợi.
Lớp này chứa hai phương thức kiểm thử, vì vậy một lần chạy sẽ thực thi cả hai: một phương thức dự đoán sẽ xảy ra ngoại lệ ArithmeticException và một phương thức khẳng định dựa trên chuỗi được trả về.
Lưu ý: Ví dụ này xuất hiện dưới ba tên khác nhau trong tài liệu gốc — danh sách gọi lớp là AirthematicTest, ảnh chụp màn hình trình chỉnh sửa hiển thị AirthematicTest1, và kết quả hiển thị là JunitTestExample. Mã nguồn giống hệt nhau trong mỗi trường hợp; chỉ khác nhau ở tên tệp.
Chúng ta hãy thực hiện và kiểm chứng kết quả. JUnit Xem báo cáo bên dưới về quá trình hoạt động của... JunitTestExample.java.
Đầu ra:
Đây là kết quả đầu ra, cho thấy bài kiểm tra đã thành công mà không có lỗi nào. tracnhư được nêu bên dưới:
Cả hai phương pháp đều thành công. Phương pháp đầu tiên thành công vì ngoại lệ ArithmeticException mà nó khai báo đã xảy ra, và phương pháp thứ hai thành công vì chuỗi trả về khớp với kết quả. Nếu phép chia không bao giờ gây ra ngoại lệ, JUnit Phương pháp đầu tiên sẽ thất bại với thông báo “Expected exception: java.lang.ArithmeticException”.
Ba cách để kiểm tra một ngoại lệ trong JUnit 4
Tham số mong đợi là tham số ngắn nhất trong ba tham số. JUnit Có 4 thành ngữ, nhưng không phải lúc nào cũng chọn đúng. Bảng so sánh chúng dựa trên hai câu hỏi quyết định sự lựa chọn: bạn có thể khẳng định thông điệp đó không, và bạn có biết dòng nào đã được sử dụng không?
| Phương pháp tiếp cận | Thông điệp khẳng định điều đó? | Ghim vạch ném? | Tốt nhất cho |
| @Test(expected = X.class) | Không | Không — bất kỳ dòng nào trong phương thức đều có thể gây ra lỗi. | Các bài kiểm tra ngắn, trong đó chỉ loại ngoại lệ là quan trọng. |
| thử / thất bại() / bắt | Vâng, bên trong khối bắt giữ | Đúng vậy — chỉ những cuộc gọi được bảo vệ mới được theo dõi. | Các bài kiểm tra phải xem xét thông điệp hoặc nguyên nhân. |
| @Rule ExpectedException | Vâng, thông qua expectMessage(). | Không | Các bộ ứng dụng cũ đã được xây dựng dựa trên các quy tắc. |
Cấu trúc hàm fail() được đề cập trong phần giới thiệu trông như thế này. Nếu lệnh gọi không gây ra lỗi, hàm fail() sẽ chạy và bài kiểm tra sẽ báo cáo thông báo mà bạn đã viết:
@Test public void testDivideByZero() { try { junitMessage.printMessage(); fail("Expected an ArithmeticException"); } catch (ArithmeticException e) { assertEquals("/ by zero", e.getMessage()); } }
Quy tắc ExpectedException nằm giữa hai quy tắc kia. Nó đã bị loại bỏ trong... JUnit 4.13 ủng hộ phương thức assertThrows được mô tả tiếp theo, vì vậy mới JUnit 4 bài kiểm tra không nên áp dụng nó.
Cách kiểm thử ngoại lệ trong JUnit 5 với assertThrows()
JUnit Mục 5 loại bỏ hoàn toàn tham số dự kiến khỏi @Test. Jupiter cung cấp assertThrows()Phương thức này nhận vào lớp ngoại lệ và một hàm lambda chứa đoạn mã cần kiểm thử. Nó trả về ngoại lệ đã bắt được, do đó thông báo, nguyên nhân và bất kỳ trường tùy chỉnh nào đều có thể được xác nhận sau đó.
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; public class AirthematicJupiterTest { JUnitMessage junitMessage = new JUnitMessage("Saurabh"); @Test public void testJUnitMessage() { ArithmeticException thrown = assertThrows( ArithmeticException.class, () -> junitMessage.printMessage()); assertEquals("/ by zero", thrown.getMessage()); } }
Ba người có liên quan khẳng định Hoàn thiện gia đình:
- assertThrows Chấp nhận kiểu ngoại lệ hoặc bất kỳ lớp con nào của nó.
- assertThrowsExactly Từ chối một lớp con, vì vậy chỉ kiểu được đặt tên mới được chấp nhận.
- assertDoesNotThrow Điều này thể hiện kỳ vọng ngược lại, rằng khối lệnh sẽ được hoàn thành một cách trơn tru.
JUnit Đoạn mã số 4 trên trang này vẫn đang chạy trên... JUnit Nền tảng được xây dựng thông qua công cụ cũ, vì vậy không cần phải viết lại bất cứ thứ gì ở trên để dự án tiếp tục hoạt động trong quá trình chuyển đổi.
Những lỗi thường gặp khi kiểm thử ngoại lệ trong JUnit
Các bài kiểm tra ngoại lệ thất bại theo một số ít cách dễ nhận biết. Mỗi hàng nêu rõ triệu chứng, nguyên nhân và cách khắc phục.
| Triệu chứng | Nguyên nhân | Sửa chữa |
| Ngoại lệ dự kiến: java.lang.ArithmeticException | Phương pháp này hoàn thành mà không gây ra lỗi. | Hãy kiểm tra xem dữ liệu đầu vào có thực sự không hợp lệ hay không, sau đó chạy lại. |
| Bài kiểm tra đạt nhưng lại xuất ra dòng sai. | Tham số mong đợi giám sát toàn bộ phương thức, bao gồm cả thiết lập. | Di chuyển phần thiết lập ra ngoài, hoặc chuyển sang sử dụng assertThrows xung quanh một lệnh gọi duy nhất. |
| Loại ngoại lệ chưa được xử lý trong trình soạn thảo | Một ngoại lệ đã được kiểm tra được ném ra nhưng chưa bao giờ được khai báo. | Thêm từ khóa `throws` vào chữ ký phương thức kiểm thử. |
| Bài kiểm tra thành công trên một lớp con mà bạn không hề dự định. | Phương thức assertThrows chấp nhận các lớp con của kiểu được đặt tên. | Hãy sử dụng assertThrowsExactly để đảm bảo khớp kiểu dữ liệu chính xác. |
| expected không phải là một thuộc tính hợp lệ | Bài kiểm tra được biên dịch dựa trên chú thích @Test của Jupiter. | Nhập org.junit.Test cho JUnit 4, hoặc chuyển sang assertThrows. |
Dòng cuối cùng là dòng khiến hầu hết mọi người gặp khó khăn trong quá trình chuyển đổi, bởi vì cả hai chú thích đều được đặt tên là @Test và chỉ có thao tác nhập mới phân biệt được chúng. Giữping một JUnit phiên bản mỗi trường hợp thử nghiệm Lớp học này tránh được toàn bộ loại vấn đề.



