2012-10-05 54 views
6

Me doy cuenta de que hay muchas preguntas similares a this one, sin embargo, después de leer la mayoría de ellas parece que tengo el mismo problema, pero por diferentes razones.Ant JUnit ClassNotFoundException

Estoy ejecutando una tarea <junit> dentro de mi compilación Ant y obtengo un ClassNotFoundException. En la mayoría de las preguntas relacionadas de forma similar (como la anterior), esto resultó en varios grados del autor simplemente no configurando la ruta de clase JUnit correctamente. Aunque puede ser lo mismo para mí, ninguna de las sugerencias a ninguna de estas otras preguntas me ha funcionado.

Mi estructura de directorios:

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 

En src/test/java/FakeObjectUnitTest.java:

// Package and imports omitted 

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

     Assert.assertEquals(x, 5); 
    } 
} 

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

Cuando ejecuto este objetivo desde la línea de comandos:

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 

Hago esto para probar que ve FakeObjectUnitTest.class en el classpath de JUnit. Sin embargo, falla con un error. Cuando entro en el informe TEST XML para esta prueba, veo lo siguiente:

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

Cuando corro Hormiga en modo detallado (-v) la única pista lo que veo son un montón de advertencias a lo largo de las líneas de :

Haciendo caso omiso de Excepción java.util.zip.ZipException: error en la apertura de cremallera de recursos de lectura de archivos x

... donde x es el nombre de un archivo de clase.

Encontré this pregunta en SO, y el problema resultó ser que el autor había agregado archivos de clase al classpath, no JAR (lo que hace que JUnit infeliz). Así que traté de eliminar main.class.path y test.class.path desde junit.class/path y luego recibí una excepción que no se puede encontrar ninguno de los archivos de clase.

¿Alguna idea o idea de lo que está pasando? Gracias de antemano, y lo siento por la pregunta -v aquí, pero pensé que cuantos más detalles, mejor.

Respuesta

5

Es necesario utilizar para estructuras de paquetes como:
From the manual:

Dondequiera que los valores de ruta-como necesitan para especificarse, se puede usar un elemento anidado. Esto toma la forma general de:

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

Así que su solución se vería así:

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

por costumbre, eres el hombre. ¡Gracias! – IAmYourFaja

2

En cuanto a la ruta de clases:

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

No se puede poner una clase individual en la ruta de clase de esa manera.En su lugar, poner el directorio que está en la base de la jerarquía de paquetes en la ruta de clase:

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

Gracias @Jesper (+1) - pero si lo notas, la única razón por la cual 'FakeObject.class' está en el classpath de JUnit es porque pasa a ser el único binario que se compila. Está en el classpath porque está dentro de 'bin/main', que es parte de' main.class.path', que a su vez es parte de 'junit.class.path', así que a menos que me falta algo,' bin/main' ya es la construcción que forma parte de la ruta de clase JUnit. – IAmYourFaja

0

modificación de maquillaje en blanco carrera junit de la siguiente manera,

  <batchtest todir="gen/reports"> 
      <fileset dir="bin/tests"> 
       <include name="**/*UnitTest*.class"/> 
      </fileset> 
     </batchtest> 
Cuestiones relacionadas