2013-01-10 133 views
1

我有一個Maven2的單元測試一些容易混淆的行爲。下面的測試代碼產生在Eclipse中運行與Maven2的不同的結果:Java文件類在Windows 7中使用相對路徑

File f = new File(JUnitConstants.TEST_FILE); 
File root = new File("."); 
Log.info("File Info:"); 
Log.info(f.toString() + (f.exists() ? " exists" : " doesn't exist")); 
Log.info(f.getAbsoluteFile().toString() + (f.getAbsoluteFile().exists() ? " exists" : " doesn't exist")); 
Log.info(root.toString() + (root.exists() ? " exists" : " doesn't exist")); 
Log.info(root.getAbsoluteFile().toString() + (root.getAbsoluteFile().exists() ? " exists" : " doesn't exist")); 

在Eclipse中,一切都存在,單元測試運行正常。在maven中,f.exists()方法返回false;所以它認爲該文件不存在!下面是從行家運行測試輸出:

2013-01-10 09:50:51,737 [main] INFO - File Info: 
2013-01-10 09:50:51,737 [main] INFO - target\test-classes\test\test.img doesn't exist 
2013-01-10 09:50:51,737 [main] INFO - C:\Users\me\code\HEAD\modules\project\target\test-classes\test\test.img exists 
2013-01-10 09:50:51,737 [main] INFO - . exists 
2013-01-10 09:50:51,737 [main] INFO - C:\Users\me\code\HEAD\modules\project\. exists 

因此,該文件存在,根目錄是我所期望的,但爲什麼的Java認爲文件不存在,使用相對路徑的時候?

我在Windows 7中,64位;使用JDK 1.6_38 32位。

+0

,你能否告訴我們'JUnitConstants.TEST_FILE'的確切價值? –

+0

當然,它是'公共靜態最終字符串TEST_FILE =「目標/測試類/測試/測試.img」;'我會注意到更改/到File.separator似乎沒有在這種情況下有所作爲。 – cneller

+0

我認爲它在Maven中因爲filepath的'target'和'test-classes'部分而被破壞。嘗試使用'「test/test.img」'作爲你的相對路徑。這個文件在你的項目結構中的位置?我認爲它應該在'/ src/test/resources /'後面跟隨你的測試包。我不確定這是否會在Eclipse中工作,但我不使用該IDE。 –

回答

0

一段時間後,我已經確定問題是萬無一失的測試過程的分叉。 Maven構建運行的指揮下類似的測試:

cmd.exe /X /C ""C:\Program Files (x86)\Java\jdk1.6.0_38\jre\bin\java" -Djava.library.path=target/test-classes -jar C:\Users\me\AppData\Local\Temp\surefirebooter6580985433891892701.jar C:\Users\me\AppData\Local\Temp\surefire8381564625923782274tmp C:\Users\me\AppData\Local\Temp\surefire2578536694398675625tmp" 

我可以運行在命令行的確切參數(引號內),Java和一切正常,但只要我把它們叉到另一個命令窗口(cmd.exe/X/C),它以同樣的方式失敗。

我已經通過禁用pom.xml文件分叉解決了這個:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <configuration> 
     <argLine>-Djava.library.path=target/test-classes</argLine> 
     <forkMode>never</forkMode> 
    </configuration> 
</plugin> 

這仍然必須是東西在我的系統配置,因爲其他Windows 7 64位計算機沒有這個問題,但關閉分叉似乎是一個解決方案。

+0

啊哈!我終於偶然發現了所有這些問題的真正原因:在註冊表中,在HKEY_CURRENT_USER \ Software \ Microsoft \ Command Processor下有一個名爲Autorun的設置。這被設置爲更改爲特定的目錄。當Maven運行單元測試時,它通過運行cmd.exe命令來實現它們,該命令在啓動任何其他操作之前運行'cd/Users/cneller'命令。難怪沒有找到任何相對路徑文件;它們與我的主目錄不相關,而是與運行cmd.exe的目錄相關。 – cneller

1

我從來沒有真正在測試中使用的new File(filepath)構造。我總是用...

String filepath = "test/test.img"; // relative to src/test/resources 
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filepath); 

或者,如果資源文件是在同一個包結構,使用它們的測試(S),你可以使用簡單的...

String filename = "test.img"; // relative to src/test/resources/package/where/tests/live 
InputStream inputStream = getClass().getResourceAsStream(filepath); 

這似乎總是在Maven和我的IDE中工作,IntelliJ IDEA

關於上面的代碼一個很好的說明,請參見this blog post

+0

謝謝你的幫助傑西。我現在要把這個粉筆寫到我的環境中。該代碼在Windows XP,Fedora 17和OS X 10.8上正常工作,但不是Windows 7。無論如何,我可以按照你的建議使用'InputStream'來解決這個問題,或者使用'getAbsoluteFile()'來測試,這應該沒問題。 – cneller