Как я могу проверить, был ли создан файл .class?
-
20-09-2019 - |
Вопрос
Я хочу модульно протестировать свой код, который должен будет создать файл .java, скомпилировать его, а затем создать соответствующий файл .class.
Как я могу создать тест, чтобы проверить, создан ли файл ".class"?Я уже добавил тест на его существование, теперь я пытаюсь проверить, является ли файл допустимым файлом класса.
Я пытался
try {
Class.forName("Hello");
throw AssertError();
} catch( ClassNotFoundException e ) {
}
program.createClass();
Class.forName("Hello");
Но я действительно не знаю, как динамически добавлять путь, по которому создается файл, в classpath .
Редактировать
Загруженный класс URL выполняет эту работу.
Вот как сейчас выглядит мой тест.
@Test
void testHello() throws MalformedURLException, ClassNotFoundException {
URL[] url = {
new URL("file:/home/oreyes/testwork/")
};
try {
new URLClassLoader(url).loadClass("Hello");
throw new AssertionError("Should've thrown ClassNotFoundException");
} catch ( ClassNotFoundException cnfe ){
}
c.process();
new URLClassLoader(url).loadClass("Hello");
}
Решение
Используйте новый экземпляр URLClassLoader
, указывающий на корневую папку, в которой вы создали файл целевого класса.Затем используйте Class.forName(String,ClassLoader);
метод с динамически созданным URLClassLoader
чтобы загрузить новый класс.
Чтобы показать, что это работает, в следующем тестовом примере будет создан исходный файл, записан некоторый Java-код в нем и скомпилирован с использованием интерфейсов Java 6 ToolProvider.Затем он динамически загрузит класс с помощью URLClassLoader и вызовет отражающий вызов к его имени класса, чтобы убедиться, что это действительно этот класс, который был сгенерирован "на лету".
@Test
public void testUrlClassLoader() throws Exception {
Random random = new Random();
String newClassName = "Foo" + random.nextInt(1000);
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
List<File> files = new ArrayList<File>();
File sourceFolder = new File(".");
File sourceFile = new File(sourceFolder, newClassName + ".java");
FileWriter fileWriter = new FileWriter(sourceFile);
fileWriter.write("public class " + newClassName + " { { System.out.println(\""
+ newClassName + " loaded\"); }}");
fileWriter.close();
files.add(sourceFile);
Iterable<? extends JavaFileObject> compilationUnits1 = fileManager
.getJavaFileObjectsFromFiles(files);
compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
fileManager.close();
URL url = sourceFolder.toURI().toURL();
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url });
Object newInstance = urlClassLoader.loadClass(newClassName).newInstance();
assertEquals(newClassName, newInstance.getClass().getName());
}
Другие советы
Вместо того чтобы загружать класс для его проверки, вы могли бы выполнить команду типа "file Hello.class " чтобы посмотреть, сообщает ли он, что это файл класса Java, или даже запустить подпроцесс java для загрузки класса за пределами вашей тестовой JVM.