Ошибка при выполнении динамически созданных тестов JUnit - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь вызвать динамически созданный тестовый класс Junit, используя код ниже

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    URL classUrl = javaClass.getParent().toFile().toURI().toURL();
    URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { classUrl });
    Class<?> clazz = Class.forName(fileName, true, classLoader);
    Object obj = clazz.newInstance();
    context.getLogger().log("Test Class Loader==>"+obj.getClass().getClassLoader()+"\n");
    JUnitCore junit = new JUnitCore();
    context.getLogger().log("JUnitCore Class Loader==>"+junit.getClass().getClassLoader()+"\n");
    junit.addListener(new TextListener(new PrintStream(outputStream)));
    Result result = junit.run(clazz);       
    return outputStream.toString();

Динамически созданный тестовый файл

public class SampleJavaFileTest {
  String EXPECTED_OUTPUT_STRING="r3plac3";

  @Test
  public void testReplaceString() {
    SampleJavaFile sample = new SampleJavaFile();

    String outputString = sample.replaceString("replace","e","3");
    Assert.assertEquals(EXPECTED_OUTPUT_STRING, outputString);
 }
}

Но я получаю ошибку как

There was 1 failure:
1) initializationError(JUnitTest)
org.junit.runners.model.InvalidTestClassError: Invalid test class 'JUnitTest':
1. No runnable methods
at org.junit.runners.ParentRunner.validate(ParentRunner.java:511)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:101)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:84)
at org.junit.runners.JUnit4.<init>(JUnit4.java:23)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder
  .runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
at org.junit.runner.Computer.getRunner(Computer.java:50)
at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:125)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:111)
at org.junit.runners.Suite.<init>(Suite.java:81)
at org.junit.runner.Computer$2.<init>(Computer.java:33)

Я попытался напечатать загрузчики классов динамически создаваемого класса и класса JUnitCore. В результате были получены следующие результаты:

   Test Class Loader==>java.net.FactoryURLClassLoader@86be70a
   JUnitCore Class Loader==>java.net.URLClassLoader@49c2faae 

При просмотре различных публикаций предлагаются ответы на использование пользовательских загрузчиков классов для решения этой проблемы. ,Можете ли вы помочь в создании собственного загрузчика классов для решения этой проблемы?

Если это не пользовательские загрузчики классов, как еще это можно решить?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Это может быть проблема, связанная с загрузчиком классов, попробуйте создать URLClassLoader с помощью конструктора и передать загрузчик классов другого тестового класса (или просто класса junit), как родительский загрузчик классов, чтобы гарантировать, что классы JUnit всегда загружаютсязагрузчик того же класса. И дважды проверьте, что это правильная аннотация, с правильным пакетом.

public URLClassLoader(URL[] urls, ClassLoader parent)

так

new URLClassLoader(urlOfToClass, SomeTestOrJUnitClass.class.getClassLoader())

https://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html#URLClassLoader(java.net.URL[],%20java.lang.ClassLoader)

0 голосов
/ 07 ноября 2019

это исключение генерируется в этом блоке кода junit

 List<Method> methods = testClass.getAnnotatedMethods(Test.class);
 if (methods.size() == 0) {
     errors.add(new Exception("No runnable methods"));
 }

Итак, я бы рекомендовал дважды проверить, что у вас определенно есть аннотация @Test для метода, и это действительно org.junit. Тест и эта аннотация доступны во время выполнения.

Вы можете проверить это, взяв klass.getDeclaredMethod ("testReplaceString") и распечатав все аннотации из него.

Если это не помогает, то вы можете отладить библиотеку Junit, поставить точку останова на исключение (обратите внимание, это исключение сгенерировано не в том же месте, где было выброшено) и проверить условия

Кстати, какую версию junit вы используете?

РЕДАКТИРОВАНИЕ: я проверил ваш код, создал новый проект в IDEA, добавил junit 4.13-rc-1 в зависимости и создал два файла.

public class SampleJavaFileTest {
    String EXPECTED_OUTPUT_STRING="r3plac3";
    @Test
    public void testReplaceString() {
        Assert.assertEquals(EXPECTED_OUTPUT_STRING, "r3plac3");
    }
}

и другой класс

public class ClassLoadDynamically {

    public static void main(String[] args) throws Exception {
        final File fileForClass = new File(SampleJavaFileTest.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { fileForClass.toURI().toURL() });
        Class<?> clazz = Class.forName("SampleJavaFileTest", true, classLoader);

        Method testReplaceString = clazz.getDeclaredMethod("testReplaceString");

        System.out.println("Get declared methods==>"+ testReplaceString);
        System.out.println("Get annotation => "+ testReplaceString.getAnnotation(org.junit.Test.class));

        JUnitCore junit = new JUnitCore();
        Result result = junit.run(clazz);

        System.out.println(result.wasSuccessful());

    }
}

Я проверил ваш код, он работает таким образом. Пожалуйста, проверьте, как вы генерируете свой код динамически, похоже, что проблема заключается в неправильной генерации байт-кода, дважды проверьте, как вы устанавливаете аннотации для метода.

Однако, я не уверен, в вашей средеконфигурация по лямбде. В любом случае, я бы рекомендовал, чтобы ваш код работал локально

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