java.lang.Exception:运行JUnits时没有runnable方法异常

时间:2014-06-20 03:57:23

标签: java junit ubuntu-12.04 junit4

我试图在Linux命令提示符上运行JUnit /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

22 个答案:

答案 0 :(得分:82)

如果您使用 JUnit 4.4核心跑步者来执行没有"@Test" method的类,您将收到此异常。 Kindly consult the link for more info.

vipin8169提供

答案 1 :(得分:15)

此解决方案适用于极少数人,通常是实施自己的JUnit测试运行者并使用单独的ClassLoader的人。

当您从另一个ClassLoader加载一个类,然后尝试从 system 类加载器加载的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中。

编辑:在回答user3486675中的问题时,您需要创建一个不委托给系统类加载器的ClassLoader,例如:

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

传递一组包含您需要的所有内容的网址。您可以通过过滤系统类路径来创建它。请注意,您不能简单地委托父ClassLoader,因为这些类将由而不是您的测试类的ClassLoader加载。

然后,您需要从此ClassLoader加载的类中启动整个JUnit作业。这里弄得一团糟。下面就是这样的东西:

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(...);

答案 2 :(得分:10)

我不得不更改导入语句:

import org.junit.jupiter.api.Test;

import org.junit.Test;

答案 3 :(得分:9)

在我的情况下,我导入了错误的包:

import org.testng.annotations.Test;

而不是

import org.junit.Test;

小心你的ide自动完成。

答案 4 :(得分:4)

我现在在测试代码上遇到了同样的问题。这是由于@RunWith注释在春季启动中引起的。我用过:

@RunWith(SpringRunner.class)

有了该注释,JUnit Vintage运行中,找不到任何测试,并给您错误。我已经删除了它,只有JUnit Jupiter正在运行,并且一切都很好。

答案 5 :(得分:3)

我也遇到了这个问题,有时甚至找不到原因。 后来我发现使用IDE的自动导入问题。那是程序的导入

基本上,我正在使用Eclipse IDE。而且我在程序中导入了错误的类"org.junit.jupiter.api.Test"而不是必需的类"org.junit.Test".,因此请在运行任何程序之前检查导入。

答案 6 :(得分:2)

我的控制器通过快捷方式进行测试:

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

我刚刚删除了“公共”,并且神奇地起作用了。

答案 7 :(得分:2)

如果不经意间混用了org.junit和org.junit.jupiter批注,您也可以获得此信息。

答案 8 :(得分:2)

就我而言,我使用了错误的for (Lin *y = x; y; ) { Lin *next = y->nxt; delete y; // deletes the object `y` points to, // so accessing `y->nxt` is not allowed anymore, // but accessing `next` is y = next; } 导入。正确的是x

答案 9 :(得分:2)

就我而言,我刚刚被禁用 // @ RunWith(SpringRunner.class)

也不例外

答案 10 :(得分:1)

我收到此错误是因为我没有正确创建自己的测试套件:

以下是我正确完成的方法:

将其放入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

运行它:

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

一次测试通过。

答案 11 :(得分:1)

对我来说,用 import org.junit.jupiter.api.Test; 替换 import org.junit.Test; 有帮助。

答案 12 :(得分:1)

如果用@RunWith(SpringRunner.class) 注释的类但是我们的类不包含任何测试方法,那么我们将面临这个问题。 解决方案:如果我们抽象我们不会得到这个,或者如果删除公开那么我们也不会遇到这个问题。

答案 13 :(得分:1)

在删除 JUnitCore.runClasses(classes);
之后,与Junit Jupiter(Junit5)@RunWith(SpringRunner.class)一起运行JunitCore时遇到类似的问题/错误 使用@SpringBootTest @FixMethodOrder(MethodSorters.NAME_ASCENDING)运行,如上面的评论所述,我能够为我的测试解决该问题。 https://stackoverflow.com/a/59563970/13542839

答案 14 :(得分:1)

如果您通过@RunWith(Suite.class) @Suite.SuiteClasses({})运行测试套件,请检查是否所有提供的类都是真正的测试类;)。

在我的情况下,这些类之一是实际的实现,而不是测试类。只是一个愚蠢的错字。

答案 15 :(得分:0)

如果你使用 import org.junit.jupiter.api.Test (Junit 5) 和@RunWith(SpringRunner.class),SpringRunner 在 Junit4 上,junit 感到困惑。 在类名之前删除 public 将作为 Junit 5 抱怨公共测试类。 从文档: JUnit5 比 JUnit4 更能容忍 Test 类的可见性,后者要求所有内容都是公开的。 在这种情况下,JUnit5 测试类可以具有除私有之外的任何可见性,但是,建议使用默认包可见性,这样可以提高代码的可读性。

答案 16 :(得分:0)

对我来说,我在类路径上添加了JUnit4.12Hamcrest1.3并将import org.testng.annotations.Test;import org.testng.annotations.*;更改为import org.junit.Test;。终于可以了!

答案 17 :(得分:0)

解决方案很简单 如果您导入

import org.junit.Test;

您必须以junit 4身份运行

右键单击->运行方式->测试配置->测试运行器->作为junit 4

答案 18 :(得分:0)

我的父测试setUp类也遇到了同样的问题,该类具有批注@RunWith(SpringRunner.class),并由其他testClasses进行了扩展。 由于setUpclass中没有测试,并且Junit试图通过注释@RunWith(SpringRunner.class)寻找一个,因此没有找到一个抛出异常

No runnable methods exception in running JUnits

我将我的父类设为抽象类,它的工作就像一个魅力。

我从这里here is my script得到了帮助。 感谢您的帮助@ froh42。

答案 19 :(得分:0)

我能够通过手动将junit jar添加到我的项目类路径来进行修复。我发现最简单的方法是在项目根目录中添加/ lib目录。然后,我只是将junit.jar放在/ lib中,而junit测试开始为我工作。

答案 20 :(得分:0)

最简单的解决方案是将@Test带注释的方法添加到存在初始化异常的类中。

在我们的项目中,我们的主类具有初始设置。我添加了@Test方法,异常消失了。

答案 21 :(得分:0)

在Eclipse中,我不得不使用New > Other > JUnit > Junit Test。使用完全相同的文本创建的Java类给了我错误,可能是因为它使用的是JUnit 3.x。