it-swarm.com.de

java.lang.Exception: Keine ausführbare Methodenausnahme beim Ausführen von JUnits

Ich versuche, die JUnit auf meinem Linux-Befehl auszuführen. Prompt /opt/junit/ enthält die erforderlichen JARS-Dateien (hamcrest-core-1.3.jar und junit.jar) und Klassendateien. Ich verwende den folgenden Befehl zum Ausführen von JUnit: 

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

TestJunit-Klasse:

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

Ich bekomme die folgende Ausnahme, wenn Sie das ausführen

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
37
vipin8169

Diese Ausnahme erhalten Sie, wenn Sie mit dem JUnit 4.4 Core Runner eine Klasse ausführen, die keinen "@Test" method. enthält.

mit freundlicher Genehmigung vipin8169

77
4aRk Kn1gh7

Diese Lösung gilt für einen sehr kleinen Prozentsatz von Benutzern, normalerweise für Benutzer, die ihre eigenen JUnit-Testläufer implementieren und einen separaten ClassLoader verwenden. 

Dies kann passieren, wenn Sie eine Klasse von einem anderen ClassLoader laden und dann versuchen, diesen Test von einer Instanz von JUnitCore auszuführen, die vom Klassenlader system geladen wurde. Beispiel:

// 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

Betrachten der 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)

Das Problem tritt tatsächlich bei BlockJUnit4ClassRunner: 169 (unter der Annahme von JUnit 4.11) auf:

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

Wo wird geprüft, welche Methoden mit @Test kommentiert werden:

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

In diesem Fall wurde Test.class mit dem System ClassLoader (d. H. Demjenigen, der JUnitCore geladen hat) geladen. Daher wurde technisch keine Ihrer Testmethoden mit dieser Anmerkung versehen.

Die Lösung besteht darin, JUnitCore in demselben ClassLoader wie die Tests selbst zu laden.


Edit: Als Antwort auf die Frage von user3486675 müssen Sie einen ClassLoader erstellen, der nicht an den Systemklassenlader delegiert, z. B .:

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

Übergeben Sie einen Satz URLs, der alles enthält, was Sie benötigen. Sie können dies erstellen, indem Sie den Systemklassenpfad filtern. Beachten Sie, dass Sie nicht einfach an den übergeordneten ClassLoader delegieren können, da diese Klassen dann vom Klassenlader Ihrer Testklassen geladen werden.

Dann müssen Sie den gesamten JUnit-Job von einer Klasse starten, die von diesem ClassLoader geladen wird. Hier wird es unordentlich. Etwas wie dieser totale Dreck unten:

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));
        }
    }
}

DANN müssen Sie den Läufer über Reflektion aufrufen:

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

In meinem Fall hatte ich ein falsches Paket importiert:

import org.testng.annotations.Test;

anstatt

import org.junit.Test;

Hüten Sie sich vor Ihrer Autovervollständigung.

8
awasik

Mein Controllertest in großer Abkürzung:

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

Ich habe gerade "public" entfernt und es hat auf magische Weise funktioniert.

4
Filip McKo

Ich habe diese Fehlermeldung erhalten, weil ich meine eigene Testsuite nicht richtig erstellt habe:

So habe ich es richtig gemacht:

Schreibe dies in Foobar.Java:

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

Schreibe dies in 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 Ich habe den hier von hier verwendet:

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

Kompiliere es:

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

Starte es: 

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

Ein Test wurde bestanden.

1
Eric Leschinski

Die einfachste Lösung besteht darin, der Klasse, in der eine Initialisierungsausnahme vorliegt, die kommentierte Methode @Test hinzuzufügen.

In unserem Projekt haben wir Hauptunterricht mit Grundeinstellungen. Ich habe die @ Test-Methode hinzugefügt und die Ausnahme ist verschwunden.

0
Jackkobec

In Eclipse musste ich New > Other > JUnit > Junit Test verwenden. Eine Java-Klasse, die mit genau demselben Text erstellt wurde, gab mir den Fehler, möglicherweise weil JUnit 3.x verwendet wurde.

0
Noumenon

Ich konnte das Problem beheben, indem ich das Junit-Glas manuell meinem Projektklassenpfad hinzufügte. Der einfachste Weg, dies zu tun, war das Hinzufügen eines/lib-Verzeichnisses im Projektstamm. Dann habe ich einfach die Datei junit.jar in/lib eingefügt und die junit-Tests haben begonnen, für mich zu arbeiten.

0
Larry E