Tôi đang tạo một JUnit TestCase cho một dự án cần tải một tệp cấu hình trong khi khởi tạo.getResourceAsStream từ JUnit
Tệp cấu hình này nằm trong dự án trong thư mục src/main/resources/config và trong quá trình xây dựng, hãy đặt nó vào thư mục/config, bên trong JAR.
Lớp khởi, đọc các tập tin từ đó sử dụng câu lệnh:
ClassLoader classloader = this.getClass().getClassLoader();
BufferedReader xmlSource = new BufferedReader(new InputStreamReader(classLoader.getResourceAsStream("/config/config.xml")));
Tôi có vấn đề là khi tôi triển khai và thực hiện jar này vào máy chủ ứng dụng nó hoạt động như mong đợi, tuy nhiên, bất cứ khi nào tôi chạy nó trong một JUnit TestCase trong Eclipse, phương thức getResrouceAsStream trả về null.
Xem xét lớp đó là my.package.MyClassTest.java và nó nằm trong src/test/java/my/package/MyClassTest.java, tôi đã thử đặt một bản sao của tệp config.xml vào thư mục nhưng không thành công như sau:
- src/test/resources/config
- src/test/resources/my/package/config
- src/test/java/my/package/config
tôi biết rằng câu hỏi tương tự đã được hỏi nhiều lần ở đây trong StackOverflow, nhưng tất cả các câu trả lời tôi thấy đề cập đến việc thay đổi cách các tập tin được nạp và, mặc dù thay đổi mã có thể là một tùy chọn, tôi muốn chỉ tìm đúng nơi cho tệp để tôi không cần sửa đổi những thứ đã hoạt động trong môi trường sản xuất.
Vì vậy, tôi nên đặt tệp này ở đâu để có thể sử dụng nó trong bài kiểm tra JUnit?
CẬP NHẬT
Tôi chỉ đưa ra các giải pháp với một thay đổi nhỏ trong các mã: Thay vì sử dụng ClassLoader để có được những tài nguyên, tôi trực tiếp sử dụng các lớp:
Class clazz = this.getClass();
BufferedReader xmlSource = new BufferedReader(new InputStreamReader(clazz.getResourceAsStream("/config/config.xml")));
Và nó đọc tập tin thành công từ src/test/resources/config/config.xml.
Tuy nhiên, có một cái gì đó rất lạ ở đây: Phương pháp Class.getResourceAsStream là:
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
Và nếu tôi gỡ lỗi nó, tôi có thể thấy rõ rằng đây getClassLoader0() lợi nhuận chính xác cùng một đối tượng (cùng một id) so với cuộc gọi trước đó, this.getClass(). getResourceAsStream() (mà tôi đã duy trì, chỉ để so sánh các giá trị) !!!
Điều gì đang xảy ra ở đây ?!
Tại sao gọi phương thức trực tiếp không hoạt động, trong khi chèn cuộc gọi phương thức mới vào giữa các tác phẩm?
Thành thật mà nói, tôi thực sự kinh ngạc trước điều này.
BTW, tôi đang sử dụng phiên bản JUnit 4.10. Có thể nó giả mạo cuộc gọi getClassLoader theo một cách nào đó không?
Rất cám ơn,
Carles
Có phải 'src/test/resources /' là thư mục nguồn trong Eclipse không? –
@SotiriosDelimanolis nếu bạn đăng câu trả lời này, tôi sẽ bỏ phiếu. –
@SotiriosDelimanolis: Vâng, đúng vậy. Thật vậy, khi tôi nhìn vào nó, tôi đã nhận ra rằng Eclipse nhận nó theo mặc định cho các dự án maven. –