2012-10-05 22 views
6

Zdaję sobie sprawę, że istnieje wiele podobnych pytań, jak this one, jednak po przeczytaniu większości z nich wydaje mi się, że mam ten sam problem, ale z różnych powodów.Ant JUnit ClassNotFoundException

Używam zadania <junit> wewnątrz mojej wersji Ant i otrzymuję numer ClassNotFoundException. W większości podobnych pytań (takich jak powyższy), okazało się, że różne stopnie autora po prostu nie konfigurowały prawidłowo ścieżki klas JUnit. Chociaż może to być dla mnie takie samo, żadna z sugestii na którekolwiek z tych innych pytań nie zadziałała dla mnie.

Moja struktura katalogów projektu:

MyProject/ 
    src/main/java/ 
     FakeObject.java 
     ...the rest of my Java main source 
    src/test/java 
     FakeObjectUnitTest.java 
     ...the rest of my Java test source 
    bin/main 
     FakeObject.class 
     ...the rest of main Java binaries 
    bin/test 
     FakeObjectUnitTest.class 
     ...the rest of main Java binaries 
    lib/main 
     ...my main dependencies 
    lib/test 
     junit-4.10.jar 
     hamcrest-1.1.jar 
     ...the rest of my test dependencies 
    gen/reports 
     ...where JUnit should be placing all test reports 
    build/ 
     build.xml 
     build.properties 

W src/test/java/FakeObjectUnitTest.java:

// Package and imports omitted 

public class FakeObjectUnitTest { 
    @Test 
    public void doSomething() { 
     int x = 5; 

     Assert.assertEquals(x, 5); 
    } 
} 

My build.xml:

<project name="" basedir=".."> 
    <!-- Main classpath. --> 
    <path id="main.class.path"> 
     <fileset dir="bin/main"/> 
    </path> 

    <!-- Test classpath. --> 
    <path id="test.class.path"> 
     <fileset dir="bin/test"/> 
    </path> 

    <!-- JUnit classpath. --> 
    <path id="junit.class.path"> 
     <fileset dir="lib/main" includes="*.jar"/> 
     <fileset dir="lib/test" includes="*.jar"/> 
     <path refid="main.class.path"/> 
     <path refid="test.class.path"/> 
    </path> 

    <!-- 
     All previous targets omitted for brevity (such as for compiling, etc.), but 
    I assure you all that they work and compile FakeObject.java/FakeObjectUnitTest.java into 
    FakeObject.class/FakeObjectUnitTest.class respectively, and place them in the correct 
bin directories. 
    --> 

    <target name="run-junit" depends="compile"> 

     <property name="junit.path" refid="junit.class.path"/> 
     <echo message="JUnit ClassPath is: ${junit.path}"/> 

     <junit printsummary="yes" haltonerror="yes" haltonfailure="yes"> 
      <classpath refid="junit.class.path"/> 

      <formatter type="xml"/> 

      <batchtest todir="gen/reports"> 
       <fileset dir="src/test/java"> 
        <include name="**/*UnitTest*.java"/> 
       </fileset> 
      </batchtest> 
     </junit> 
    </target> 
</project> 

Gdy ten cel z linii poleceń:

run-junit: 
    [echo] Conducting unit tests with JUnit. 
    [echo] JUnit ClassPath is: /<path-to-my-project>/MyProject/lib/test/hamcrest-1.1.jar:/<path-to-my-project>/MyProject/lib/test/junit-4.10.jar:/<path-to-my-project>/MyProject/bin/main/com/myproject/client/FakeObject.class:/<path-to-my-project>/MyProject/bin/test/com/myproject/client/FakeObjectUnitTest.class 
    [junit] Running com.myproject.client.FakeObjectUnitTest 
    [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec 

Robię to, aby udowodnić, że widzi FakeObjectUnitTest.class na ścieżce klasy JUnit. Jednak błąd kończy się niepowodzeniem. Kiedy idę do raportu TEST XML dla tego testu, widzę następujące:

<error message="com.myproject.client.FakeObjectUnitTest" type="java.lang.ClassNotFoundException">java.lang.ClassNotFoundException: com.myproject.client.FakeObjectUnitTest 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:247) 
</error> 

Gdy uruchomię Ant w trybie gadatliwym (-v) jedynym wskazówkę widzę to banda ostrzeżeń wzdłuż linii :

Ignorując Wyjątek java.util.zip.ZipException: błąd odczytu pliku zip otwarcie zasobu x

... gdzie x jest nazwą pliku klasy.

Znalazłem pytanie na SO, a problem okazał się, że autor dodał pliki klas do ścieżki klasy, a nie JARs (co czyni JUnit nieszczęśliwym). Więc próbowałem usunąć main.class.path i test.class.path z junit.class/path, a następnie otrzymuję wyjątek, że nie można znaleźć żadnego pliku klasy.

Jakieś pomysły i przemyślenia na temat tego, co się dzieje? Z góry dziękuję i przepraszam za pytanie -v, ale pomyślałem, że im więcej szczegółów, tym lepiej.

Odpowiedz

5

Trzeba użyć pakietu podobny strukturach:
From the manual:

Gdziekolwiek wartości ścieżki, jak trzeba do określenia można użyć elementu zagnieżdżonego. Dzieje ogólną postać:

<classpath> 
     <pathelement path="${classpath}"/> 
     <pathelement location="lib/helper.jar"/> 
    </classpath> 

Więc rozwiązaniem będzie wyglądać następująco:

<!-- JUnit classpath. --> 
<path id="junit.class.path"> 
    <fileset dir="lib/main" includes="*.jar"/> 
    <fileset dir="lib/test" includes="*.jar"/> 
    <pathelement location="bin/main"/> 
    <pathelement location="bin/test"/> 
</path> 
+0

jak zwykle, jesteś mężczyzną. Dziękuję Ci! – IAmYourFaja

2

Patrząc na ścieżce klas:

...:/<path-to-my-project>/MyProject/bin/main/com/myproject/client/FakeObject.class:... 

nie można umieścić indywidualny klasę w ścieżce klasy takiego.Zamiast umieścić katalog, który znajduje się u podstawy hierarchii opakowaniu w ścieżce klasy:

...:/<path-to-my-project>/MyProject/bin/main:... 
+0

Dzięki @Jesper (+1) - ale jeśli zauważysz, jedynym powodem, dla którego 'FakeObject.class' znajduje się w ścieżce klasy JUnit, jest to, że jest to jedyny plik binarny, który jest kompilowany. Jest w ścieżce klas, ponieważ znajduje się wewnątrz 'bin/main', który jest częścią' main.class.path', który z kolei jest częścią 'junit.class.path', więc jeśli czegoś nie brakuje,' ' bin/main' jest już konstrukcją, która jest częścią ścieżki klasy JUnit. – IAmYourFaja

0

dokonania modyfikacji w celu wykonywania junit następująco,

  <batchtest todir="gen/reports"> 
      <fileset dir="bin/tests"> 
       <include name="**/*UnitTest*.class"/> 
      </fileset> 
     </batchtest> 
Powiązane problemy