Подтвердить что ты не робот

Java.lang.Exception: исключение исключений runnable в запуске JUnits

Я пытаюсь запустить JUnit в командной строке Linux /opt/junit/ содержит необходимые JARS (hamcrest-core-1.3.jar и junit.jar) и файлы классов, и я использую следующую команду для запуска JUnit:

java -cp hamcrest-core-1.3.jar:junit.jar:. org.junit.runner.JUnitCore  TestRunner

Класс TestJunit:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {
   @Test
   public void testAdd() {
      String str= "Junit is working fine";
      assertEquals("Junit is working fine",str);
   }
}

TestRunner:

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(TestJunit.class);
      for (Failure failure : result.getFailures()) {
         System.out.println("fail ho gaya"+failure.toString());
      }
      System.out.println("passed:"+result.wasSuccessful());
   }
}  

Я получаю следующее исключение при запуске этого

JUnit version 4.11
.E
Time: 0.003
There was 1 failure:
1) initializationError(TestRunner)
java.lang.Exception: No runnable methods
    at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:169)
    at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:104)
    at org.junit.runners.ParentRunner.validate(ParentRunner.java:355)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:57)
    at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runner.Computer.getRunner(Computer.java:40)
    at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
    at org.junit.runners.Suite.<init>(Suite.java:80)
    at org.junit.runner.Computer.getSuite(Computer.java:28)
    at org.junit.runner.Request.classes(Request.java:75)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
    at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96)
    at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47)
    at org.junit.runner.JUnitCore.main(JUnitCore.java:40)

FAILURES!!!
Tests run: 1,  Failures: 1
4b9b3361

Ответ 2

В моем случае я импортировал неправильный пакет:

import org.testng.annotations.Test;

вместо

import org.junit.Test;

Остерегайтесь своего автозаполнения.

Ответ 3

Это решение будет применяться к очень маленькому проценту людей, как правило, люди, реализующие свои собственные тестовые ролики JUnit и использующие отдельный ClassLoader.

Это может произойти, когда вы загружаете класс из другого ClassLoader, а затем пытаетесь запустить этот тест из экземпляра JUnitCore, загруженного из загрузчика системного класса. Пример:

// Load class
URLClassLoader cl = new URLClassLoader(myTestUrls, null);
Class<?>[] testCls = cl.loadClass("com.gubby.MyTest");

// Run test
JUnitCore junit = new JUnitCore();
junit.run(testCls); // Throws java.lang.Exception: No runnable methods

Глядя на трассировку стека:

java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:169)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:104)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:355)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:57)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.junit.runner.JUnitCore.run(JUnitCore.java:138)

Проблема на самом деле возникает в BlockJUnit4ClassRunner: 169 (при условии, что JUnit 4.11):

https://github.com/junit-team/junit/blob/r4.11/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java#L95

Где он проверяет, какие методы аннотируются с помощью @Test:

protected List<FrameworkMethod> computeTestMethods() {
    return getTestClass().getAnnotatedMethods(Test.class);
}

В этом случае Test.class будет загружен системой ClassLoader (т.е. той, которая загрузила JUnitCore), поэтому технически ни один из ваших тестовых методов не будет аннотирован этой аннотацией.

Решение заключается в загрузке JUnitCore в тот же ClassLoader, что и сами тесты.


Изменить. В ответ на вопрос от пользователя 3486675 вам необходимо создать ClassLoader, который не делегирует загрузку системного класса, например:

private static final class IsolatedURLClassLoader extends URLClassLoader {
    private IsolatedURLClassLoader(URL[] urls) {
        // Prevent delegation to the system class loader.
        super(urls, null);
    }
}

Передайте этот набор URL-адресов, которые включают все, что вам нужно. Вы можете создать это, отфильтровав путь к системе. Обратите внимание, что вы не можете просто делегировать родительский ClassLoader, потому что тогда эти классы будут загружены этим, а не ClassLoader ваших тестовых классов.

Затем вам нужно запустить все JUnit-задания из класса, загруженного этим ClassLoader. Здесь беспорядок. Что-то вроде этой полной грязи ниже:

public static final class ClassLoaderIsolatedTestRunner {

    public ClassLoaderIsolatedTestRunner() {
        // Disallow construction at all from wrong ClassLoader
        ensureLoadedInIsolatedClassLoader(this);
    }

    // Do not rename.
    public void run_invokedReflectively(List<String> testClasses) throws BuildException {
        // Make sure we are not accidentally working in the system CL
        ensureLoadedInIsolatedClassLoader(this);

        // Load classes
        Class<?>[] classes = new Class<?>[testClasses.size()];
        for (int i=0; i<testClasses.size(); i++) {
            String test = testClasses.get(i);
            try {
                classes[i] = Class.forName(test);
            } catch (ClassNotFoundException e) {
                String msg = "Unable to find class file for test ["+test+"]. Make sure all " +
                        "tests sources are either included in this test target via a 'src' " +
                        "declaration.";
                throw new BuildException(msg, e);
            }
        }

        // Run
        JUnitCore junit = new JUnitCore();
        ensureLoadedInIsolatedClassLoader(junit);
        junit.addListener(...);
        junit.run(classes);
    }

    private static void ensureLoadedInIsolatedClassLoader(Object o) {
        String objectClassLoader = o.getClass().getClassLoader().getClass().getName();

        // NB: Can't do instanceof here because they are not instances of each other.
        if (!objectClassLoader.equals(IsolatedURLClassLoader.class.getName())) {
            throw new IllegalStateException(String.format(
                    "Instance of %s not loaded by a IsolatedURLClassLoader (loaded by %s)",
                    cls, objectClassLoader));
        }
    }
}

Затем, вам нужно вызвать бегун через отражение:

Class<?> runnerClass = isolatedClassLoader.loadClass(ClassLoaderIsolatedTestRunner.class.getName());

// Invoke via reflection (List.class is OK because it just uses the string form of it)
Object runner = runnerClass.newInstance();
Method method = runner.getClass().getMethod("run_invokedReflectively", List.class);
method.invoke(...);

Ответ 4

Мой тестовый контроллер в большом ярлыке:

@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskControllerTest {
   //...
   //tests
   //
}

Я просто удалил "public" и волшебным образом это сработало.

Ответ 5

Я получил эту ошибку, потому что я не создал свой собственный тестовый набор правильно:

Вот как я сделал это правильно:

Поместите это в Foobar.java:

public class Foobar{
    public int getfifteen(){
        return 15;
    }
}

Поместите это в FoobarTest.java:

import static org.junit.Assert.*;
import junit.framework.JUnit4TestAdapter;
import org.junit.Test;
public class FoobarTest {
    @Test
    public void mytest() {
        Foobar f = new Foobar();

        assert(15==f.getfifteen());
    }
    public static junit.framework.Test suite(){
       return new JUnit4TestAdapter(FoobarTest.class);
    }
}

Загрузите junit4-4.8.2.jar Я использовал один здесь:

http://www.java2s.com/Code/Jar/j/Downloadjunit4jar.htm

Скомпилируйте его:

javac -cp .:./libs/junit4-4.8.2.jar Foobar.java FoobarTest.java

Запустите его:

[email protected] /home/el $ java -cp .:./libs/* org.junit.runner.JUnitCore FoobarTest
JUnit version 4.8.2
.
Time: 0.009    
OK (1 test)

Прошло одно испытание.

Ответ 6

В Eclipse мне пришлось использовать New > Other > JUnit > Junit Test. Java-класс, созданный с таким же текстом, дал мне ошибку, возможно, потому, что он использовал JUnit 3.x.

Ответ 7

Самое простое решение - добавить аннотированный метод @Test в класс, где присутствует исключение инициализации.

В нашем проекте у нас есть основной класс с начальными настройками. Я добавил метод @Test, исключение исчезло.

Ответ 8

Мне удалось исправить, вручную добавив банку junit к моему classpath проекта. Я нашел самый простой способ сделать это, добавив каталог /lib в корневой каталог проекта. Затем я просто помещаю junit.jar в /lib, и тесты junit начинают работать на меня.