Tôi nghĩ câu hỏi này cần một câu trả lời cập nhật, vì hầu hết các câu trả lời ở đây đã khá lỗi thời.
Đầu tiên đối với câu hỏi của OP:
Tôi nghĩ rằng nó được chấp nhận khá tốt rằng việc giới thiệu khái niệm "dự kiến excetion" vào JUnit là một động thái tồi, vì ngoại lệ đó có thể được đưa ra ở bất cứ đâu và nó sẽ vượt qua bài kiểm tra. Nó hoạt động nếu bạn ném (và khẳng định trên) các ngoại lệ rất cụ thể cho miền, nhưng tôi chỉ ném những loại ngoại lệ đó khi tôi đang làm việc trên mã cần phải hoàn toàn không tinh khiết, - hầu hết APIS sẽ chỉ đơn giản là ném các ngoại lệ được tích hợp sẵn như IllegalArgumentException
hoặc IllegalStateException
. Nếu hai lệnh gọi của bạn thực sự có thể tạo ra những ngoại lệ này, thì @ExpectedException
chú thích sẽ hiển thị màu xanh cho bài kiểm tra của bạn ngay cả khi nó sai dòng dẫn đến ngoại lệ!
Đối với tình huống này, tôi đã viết một lớp mà tôi chắc rằng nhiều người khác ở đây đã viết, đó là một assertThrows
phương pháp:
public class Exceptions {
private Exceptions(){}
public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){
try{
actionThatShouldThrow.run();
fail("expected action to throw " + expectedException.getSimpleName() + " but it did not.");
}
catch(Exception e){
if ( ! expectedException.isInstance(e)) {
throw e;
}
}
}
}
phương thức này chỉ trả về nếu ngoại lệ được ném ra, cho phép bạn thực hiện thêm các xác nhận / xác minh trong thử nghiệm của mình.
với cú pháp java 8, bài kiểm tra của bạn trông rất đẹp. Dưới đây là một trong những thử nghiệm đơn giản hơn trên mô hình của chúng tôi sử dụng phương pháp:
@Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
AxisRange range = new AxisRange(0,100);
Runnable act = () -> range.setLowerBound(200);
assertThrows(IllegalArgumentException.class, act);
}
những bài kiểm tra này hơi khó hiểu vì bước "hành động" không thực sự thực hiện bất kỳ hành động nào, nhưng tôi nghĩ ý nghĩa vẫn khá rõ ràng.
cũng có một thư viện nhỏ nhỏ trên maven có tên là catch-exception sử dụng cú pháp kiểu mockito để xác minh rằng các ngoại lệ được ném ra. Nó trông khá đẹp, nhưng tôi không phải là một fan hâm mộ của proxy động. Điều đó nói rằng, có cú pháp rất mượt mà nó vẫn hấp dẫn:
List myList = new ArrayList();
catchException(myList).get(1);
assert caughtException() instanceof IndexOutOfBoundsException;
Cuối cùng, đối với tình huống mà tôi gặp phải để truy cập chủ đề này, có một cách để bỏ qua các bài kiểm tra nếu một số conidition được đáp ứng.
Hiện tại, tôi đang làm việc để nhận một số DLL được gọi thông qua một thư viện gốc-thư viện java có tên là JNA, nhưng máy chủ xây dựng của chúng tôi ở trong ubuntu. Tôi muốn cố gắng thúc đẩy loại phát triển này bằng các bài kiểm tra JUnit - ngay cả khi chúng khác xa "đơn vị" vào thời điểm này--. Những gì tôi muốn làm là chạy kiểm tra nếu tôi đang sử dụng máy cục bộ, nhưng bỏ qua kiểm tra nếu chúng tôi đang sử dụng ubuntu. JUnit 4 có một điều khoản cho điều này, được gọi là Assume
:
@Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
URL url = DLLTestFixture.class.getResource("USERDLL.dll");
String path = url.toURI().getPath();
path = path.substring(0, path.lastIndexOf("/"));
NativeLibrary.addSearchPath("USERDLL", path);
Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);
assertThat(dll).isNotNull();
}