java.lang.Exception:运行 JUnit 时没有可运行的方法异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24319697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.lang.Exception: No runnable methods exception in running JUnits
提问by vipin8169
I am trying to run the JUnit on my Linux command prompt /opt/junit/
contains the necessary JARS(hamcrest-core-1.3.jar and junit.jar) and class files and I am using the following command to run the JUnit:
我试图在我的 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 class:
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());
}
}
I am getting the following exception on running this
运行此程序时出现以下异常
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.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
采纳答案by 4aRk Kn1gh7
You will get this exception, if you use the JUnit 4.4 core runnerto execute a class that has no "@Test" method
.
Kindly consult the link for more info.
如果您使用JUnit 4.4 核心运行器执行没有"@Test" method
.
请查阅链接以获取更多信息。
courtesy vipin8169
礼貌 vipin8169
回答by Eric Leschinski
I got this error because I didn't create my own test suite correctly:
我收到此错误是因为我没有正确创建自己的测试套件:
Here is how I did it correctly:
这是我正确执行的方法:
Put this in Foobar.java
:
把这个放在Foobar.java
:
public class Foobar{
public int getfifteen(){
return 15;
}
}
Put this in FoobarTest.java
:
把这个放在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);
}
}
Download junit4-4.8.2.jar
I used the one from here:
下载junit4-4.8.2.jar
我从这里使用的:
http://www.java2s.com/Code/Jar/j/Downloadjunit4jar.htm
Compile it:
编译它:
javac -cp .:./libs/junit4-4.8.2.jar Foobar.java FoobarTest.java
Run it:
运行:
el@failbox /home/el $ java -cp .:./libs/* org.junit.runner.JUnitCore FoobarTest
JUnit version 4.8.2
.
Time: 0.009
OK (1 test)
One test passed.
一项测试通过了。
回答by gubby
This solution will apply to a very small percentage of people, typically people implementing their own JUnit test runners and using a separate ClassLoader.
此解决方案将适用于极少数人,通常是实现自己的 JUnit 测试运行器并使用单独的类加载器的人。
This can happen when you load a class from a different ClassLoader, then attempt to run that test from an instance of JUnitCore loaded from the systemclass loader. Example:
当您从不同的 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
Looking at the stack trace:
查看堆栈跟踪:
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)
The problem actually occurs at BlockJUnit4ClassRunner:169 (assuming JUnit 4.11):
问题实际上发生在 BlockJUnit4ClassRunner:169(假设 JUnit 4.11):
Where it checks which methods are annotated with @Test
:
它检查哪些方法被注释为@Test
:
protected List<FrameworkMethod> computeTestMethods() {
return getTestClass().getAnnotatedMethods(Test.class);
}
In this case, Test.class
will have been loaded with the systemClassLoader (i.e. the one that loaded JUnitCore), therefore technically none of your test methods will have been annotated with that annotation.
在这种情况下,Test.class
将使用系统类加载器(即加载 JUnitCore 的那个)加载,因此从技术上讲,您的任何测试方法都不会使用该注释进行注释。
Solution is to load JUnitCore in the same ClassLoader as the tests themselves.
解决方案是在与测试本身相同的 ClassLoader 中加载 JUnitCore。
Edit: In answer to the question from user3486675, you need to create a ClassLoader that doesn't delegate to the system class loader, e.g.:
编辑:在回答 user3486675 的问题时,您需要创建一个不委托给系统类加载器的类加载器,例如:
private static final class IsolatedURLClassLoader extends URLClassLoader {
private IsolatedURLClassLoader(URL[] urls) {
// Prevent delegation to the system class loader.
super(urls, null);
}
}
Pass this a set of URLs that includes everything you need. You can create this by filtering the system classpath. Note that you cannot simply delegate to the parent ClassLoader, because those classes would then get loaded by that rather than the ClassLoader of your test classes.
传递一组包含您需要的所有内容的 URL。您可以通过过滤系统类路径来创建它。请注意,您不能简单地委托给父类加载器,因为这些类将被加载,而不是由测试类的类加载器加载。
Then you need to kick off the whole JUnit job from a class loaded by this ClassLoader. It gets messy here. Something like this utter filth below:
然后,您需要从此 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));
}
}
}
THEN, you need to invoke the runner via reflection:
然后,您需要通过反射调用运行程序:
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(...);
回答by awasik
In my case I had wrong package imported:
就我而言,我导入了错误的包:
import org.testng.annotations.Test;
instead of
代替
import org.junit.Test;
Beware of your ide autocomplete.
当心你的ide自动完成。
回答by Noumenon
In Eclipse, I had to use New > Other > JUnit > Junit Test
. A Java class created with the exact same text gave me the error, perhaps because it was using JUnit 3.x.
在 Eclipse 中,我不得不使用New > Other > JUnit > Junit Test
. 使用完全相同的文本创建的 Java 类给了我错误,可能是因为它使用的是 JUnit 3.x。
回答by Hymankobec
The simplest solution is to add @Test annotated method to class where initialisation exception is present.
最简单的解决方案是将 @Test 注释方法添加到存在初始化异常的类中。
In our project we have main class with initial settings. I've added @Test method and exception has disappeared.
在我们的项目中,我们有带有初始设置的主类。我添加了@Test 方法,异常消失了。
回答by Filip McKo
My controller test in big shortcut:
我的控制器测试大捷径:
@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskControllerTest {
//...
//tests
//
}
I just removed "public" and magically it worked.
我刚刚删除了“public”并且神奇地起作用了。
回答by Larry E
I was able to fix by manually adding the junit jar to my project classpath. The easiest way I found to do this was by adding a /lib directory in the project root. Then i just put the junit.jar inside /lib and junit tests starting working for me.
我能够通过手动将 junit jar 添加到我的项目类路径来修复。我发现最简单的方法是在项目根目录中添加一个 /lib 目录。然后我将 junit.jar 放在 /lib 中,junit 测试开始为我工作。
回答by René H?hle
I had the same problem now with testing code. That was caused in spring boot because of the @RunWith
annotation. I have used:
我现在在测试代码时遇到了同样的问题。那是由于@RunWith
注释在spring boot中引起的。我用过了:
@RunWith(SpringRunner.class)
With that annotation there is JUnit Vintage running which can't find any tests and gives you the error. I have removed that and only JUnit Jupiter is running and everything is fine.
使用该注释,JUnit Vintage 正在运行,它找不到任何测试并给出错误。我已经删除了它,只有 JUnit Jupiter 正在运行,一切都很好。
回答by Taylor
You can also get this if you mix org.junit and org.junit.jupiter annotations inadvertently.
如果您不小心混合了 org.junit 和 org.junit.jupiter 注释,您也可以得到这个。