2013-02-28 70 views
8

假設我有一個傳統的JUnit測試套件,其中包括以下測試:解決Java類路徑地獄

public class AwesomeTest { 
    public void testBusinessLogic() { 
    ... 
    [awesome mocking library] 
    ... 
    } 
} 

public class AmazingTest { 
    public void testBusinessProcess() { 
    ... 
    [amazing xml operation] 
    ... 
    } 
} 

現在假設真棒嘲諷庫依靠真棒BCEL字節碼生成庫,包含類org.useful.XMLClass,這個庫有版本1的XMLClass。

現在假設Amazing Xml操作依賴於包含類org.useful.XMLClass的Amazing Xml庫,並且此庫具有XML Class的第2版。

同時假定類2版本與版本1向後兼容 - 所以它永遠版本在classpath中具有更高的優先級 - 它打破了其他版本的依賴關係。

另外,假設有400次測試,依靠真棒嘲弄庫 - 所以重寫不是一個理想的選擇。

同時假定一些關鍵的業務功能,已建成以驚人的XML libary - 和強烈優選不重寫。

你如何解決這個類路徑地獄的情況 - 從運行螞蟻測試分開(假設你用Ant運行它們)有兩個不同的手動排序類路徑和手動確定測試子組的兩倍? (我打開自定義類加載器的想法 - 但似乎差不多的水平可維護性與螞蟻的解決方案的雙定製類路徑)

+0

是的,多數民衆贊成在地獄。錯誤似乎與字節碼發生器捆綁在一起的XML文件。我會建議更新你的模擬庫。 – Perception 2013-02-28 12:26:10

+0

也許你可以得到「Awesome BCEL字節碼生成庫」的源代碼,並創建一個依賴類org.useful.XMLClass的重命名版本的分支。 – gontard 2013-02-28 12:28:52

+1

我同意沒有簡單的答案。也許你可以嘗試使用自定義類加載器......但這看起來似乎比它的價值更努力。我會用XML庫或模擬操作的新庫重寫測試。 – RudolphEst 2013-02-28 12:43:14

回答

3

我相信一個相當透明的解決方案可能是使用Java代理和自定義類裝載機。這個想法如下:

  1. 使用Instrumentation Framework(java代理程序)加載它們時攔截類。當您檢測到Awesome Mocking Library中的類時,請將所有對org.useful.XMLClass的引用替換爲例如intercepted.org.useful.XMLClass
  2. 創建一個自定義的類裝載器,在您檢查所請求的類是intercepted.org.useful.XMLClass。如果是,請加載由Mocking Library使用的版本XMLClass。所有其他請求都可以默認處理。

運行測試時,使用自定義類加載器並附加java代理,並且所有內容都應該正常運行,就好像沒有依賴衝突一樣。

+0

這真的很棒。有沒有一種方法來加載現有類路徑的副本版本並在運行時對其進行修改 - 即同樣的效果,但不使用代理? – hawkeye 2013-02-28 21:46:34

+0

我不完全確定你的意思,但是如果不使用代理來區分不同版本的XMLClass,運行時如何能夠從哪個點決定使用哪個版本? – Steven 2013-02-28 23:17:07

+0

優秀的解決方案! – gontard 2013-03-19 12:06:16

0

我認爲史蒂芬的答案是偉大的 - 爲了完整起見,因爲這個問題有這麼多的選票 - 我想和大家分享我們所認爲的替代品(包括壞的)

  1. 分區測試(或一些測試)進入不同的類路徑順序 (劣勢 - 可能導致您錯過其他測試的重要問題 - 不是一個可行的選項)
  2. 回滾令人驚歎的xml操作並實現另一種方式(由於投資在這方面的使用,以及其他行動已經耗盡的事實 - 這是被駁回的)
  3. 重寫使用新的嘲弄庫測試(這是在長期良好 - 在短期內這一工程以比我們目前的項目更大,因爲有成百上千)
  4. 打造的定製版使用更新版本的org.useful.XMLClass(結果比我們目前的項目更大)的驚人嘲笑庫
  5. 從源文件中提取出有問題的類,並將舊版本放在測試類路徑上覆蓋源庫這與其他幾個課程糾纏在一起 - 所以這不是微不足道的)
  6. 在上面使用史蒂文的奇妙創意 - 再次證明這不是微不足道的
  7. 使用@Ignore設置測試 - 並將它們放入隊列中,以便在未來的項目中進行重寫。