2012-10-05 16 views
6

Tôi nhận thấy có rất nhiều câu hỏi tương tự như this one, tuy nhiên sau khi đọc qua hầu hết trong số họ tôi dường như có cùng một vấn đề, nhưng vì lý do khác nhau.Ant JUnit ClassNotFoundException

Tôi đang chạy tác vụ <junit> bên trong bản dựng Ant của mình và đang nhận được ClassNotFoundException. Trong hầu hết các câu hỏi liên quan đến tương tự (như ở trên), điều này hóa ra là các mức độ khác nhau của tác giả chỉ đơn giản là không cấu hình đúng classpath JUnit. Mặc dù nó có thể rất giống với tôi, nhưng không có gợi ý nào cho bất kỳ câu hỏi nào khác trong số những câu hỏi này đã làm việc cho tôi.

My cấu trúc thư mục dự án:

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 

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

Khi tôi chạy được mục tiêu này từ dòng lệnh:

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 

Tôi làm điều này để chứng minh rằng nó thấy FakeObjectUnitTest.class trên đường dẫn lớp JUnit. Tuy nhiên, nó không thành công với một lỗi. Khi tôi đi vào báo cáo kiểm tra XML cho thử nghiệm này, tôi thấy như sau:

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

Khi tôi chạy Ant trong chế độ verbose (-v) chỉ gợi ý tôi thấy một loạt các cảnh báo dọc theo dòng :

Bỏ qua ngoại lệ java.util.zip.ZipException: lỗi trong việc mở tập tin zip đọc tài nguyên x

... nơi x là tên của một tập tin lớp.

Tôi đã tìm thấy this câu hỏi về SO và vấn đề hóa ra là tác giả đã thêm tệp lớp vào đường dẫn lớp chứ không phải JAR (khiến JUnit không hài lòng). Vì vậy, tôi đã thử xóa main.class.pathtest.class.path từ junit.class/path và sau đó tôi nhận được ngoại lệ là không thể tìm thấy tệp nào trong lớp.

Bất kỳ ý tưởng hay suy nghĩ nào về những gì đang diễn ra? Cảm ơn trước và xin lỗi vì câu hỏi -v ở đây, nhưng tôi đã tìm hiểu thêm chi tiết, càng tốt.

Trả lời

5

Bạn cần phải sử dụng cho các cấu trúc gói như:
From the manual:

Bất cứ nơi nào giá trị con đường giống như cần để được chỉ định, một phần tử lồng nhau có thể được sử dụng. Này có dạng tổng quát của:

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

Vì vậy, giải pháp của bạn sẽ trông như thế:

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

mỗi bình thường, bạn là người đàn ông. Cảm ơn bạn! – IAmYourFaja

2

Nhìn vào classpath của bạn:

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

Bạn không thể đặt một lớp cá nhân trong classpath như thế.Thay vào đó, hãy đặt thư mục đó là tại các cơ sở của hệ thống phân cấp gói của bạn trong classpath:

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

Cảm ơn @Jesper (1) - nhưng nếu bạn nhận thấy, lý do duy nhất tại sao 'FakeObject.class' nằm trong classpath JUnit là vì nó xảy ra là nhị phân duy nhất được biên dịch. Nó nằm trong classpath bởi vì nó nằm trong 'bin/main', là một phần của' main.class.path', mà lần lượt là một phần của 'junit.class.path', vì vậy trừ khi tôi thiếu một cái gì đó,' bin/main' đã là cấu trúc là một phần của classpath JUnit. – IAmYourFaja

0

làm thay đổi trong mục tiêu chạy junit như sau,

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