JUnitCore не загружает библиотеки, необходимые в тестовых примерах - PullRequest
1 голос
/ 09 марта 2012

Я пытаюсь написать метод, который динамически запускает тест external class '.Я могу запустить тесты, которые используют только библиотеки JDK, однако, когда я запускаю тест, который использует другую библиотеку, такую ​​как org.jmock.Mockery, объект Result, возвращаемый JUnitCore.run (args), имеет следующую ошибку:

[initializationError(package.TestClass): org/jmock/Mockery]
java.lang.NoClassDefFoundError: org/jmock/Mockery

com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.

Излишне говорить, что тесты запускаются и проходят, если я запускаю их из их первоначального проекта в Eclipse.

Я считаю, что проблема связана с classpath, так как ClassLoader, похоже, загружает только тестируемый класси не загружать зависимости (например, jar-файлы), определенные в пути к классам внешнего проекта.Я не знаю, как динамически загружать jar-файлы в исполняемое приложение.

Ниже приведен код загрузки класса и запуска тестов.

URL url = new File("E:\eclipseProjectName\bin\").toURL();
final URL[] urls = new URL[] { url };
final ClassLoader cl = new URLClassLoader(urls);
@SuppressWarnings("rawtypes")
final Class cls = cl.loadClass("package.ClassName");
final JUnitCore core = new JUnitCore();
final Result result = new JUnitCore().run(Request.method(cls, "methodName"));

Заранее спасибо,

Марк Кашиа

Ответы [ 2 ]

0 голосов
/ 15 июля 2016

Если вы хотите загрузить библиотеки, которые вы используете в приложении, в котором выполняются тесты, вам нужно настроить URLClassLoader для загрузки вашего текущего загрузчика классов, а затем ссылку на классы, которые вы пытаетесь протестировать

 URLClassLoader cl = new URLClassLoader(classLoaderUrls, getClass().getClassLoader());

Вот пример, который динамически загружает классы из фляги.Если вы хотите загрузить только один класс по его имени, вы можете, как вы делали выше.

    File pathToJar = new File(jarPath);

    JarFile jarFile;
    jarFile = new JarFile(pathToJar);
    Enumeration<JarEntry> e = jarFile.entries();

    URL[] classLoaderUrls = new URL[]{pathToJar.toURI().toURL()};

    URLClassLoader cl = new URLClassLoader(classLoaderUrls, getClass().getClassLoader());
    while (e.hasMoreElements()) {

        // load all the classes in the jar (or you can set it up to use the exact class/method name as you did above
        JarEntry je = e.nextElement();
        if(je.isDirectory() || !je.getName().endsWith(".class")){
            continue;
        }
        // -6 because of .class
        String className = je.getName().substring(0,je.getName().length()-6);
        className = className.replace('/', '.');
        Class c = cl.loadClass(className);


        JUnitCore junit = new JUnitCore();
        Result result = junit.runClasses(c);
        // check for failed/ passed tests here

     }
0 голосов
/ 09 марта 2012

Я не уверен, что вы подразумеваете под:

Я полагаю, что проблема связана с classpath, так как ClassLoader, похоже, только загружает тестируемый класс и не загружает зависимости (например,jars), определенный в classpath внешнего проекта .

Если вы хотите получить доступ к классу в java, вы должны либо поместить его в classpath, либо найти и загрузить его самостоятельно.Кажется, вы добавляете путь к корзине проектов Eclipse в путь к классам, используя собственный загрузчик классов, но Mockery не добавляется в путь к классам.Путь Eclipse bin содержит только те классы, которые вы скомпилировали.Вам нужно будет либо специально загрузить Mockery jar, либо, что лучше, просто поместить все в classpath jvm, используя java -cp.

ОК, я начинаю понимать проблему.Вы пытаетесь запустить набор тестов в чужом проекте, но он не работает, если тест ссылается на другие зависимости.Короткий ответ: это сложно.Вы пытаетесь выяснить, какие классы вам нужно добавить в ваш classLoader, основываясь на ссылочных классах / банках внешнего проекта.

Есть несколько способов сделать это.Если вы уверены, что внешний проект построен с помощью Eclipse, то вы можете посмотреть на .project и .classpath, чтобы найти зависимости внешнего проекта.Это не просто, потому что они могут содержать ссылки на другие контейнеры.Это .classpath из одного из моих проектов:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
  <classpathentry kind="src" output="target/classes" path="src/main/java"/>
  <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
  <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
  <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
  <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
  <classpathentry kind="output" path="target/classes"/>
</classpath>

Содержит ссылки на контейнеры, такие как контейнер Maven.Если вы считаете, что это достижимо для ваших проектов, это может быть одним из способов достижения этого.Гораздо лучшим способом было бы принудительное использование maven или аналогичного, и тогда вы могли бы запустить тесты просто

$ mvn test

с дополнительным бонусом: если вы будете запускать и создавать проекты под jenkins, вы будететакже получайте хорошие отчеты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...