Вопрос

Я хочу модульно протестировать свой код, который должен будет создать файл .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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top