2011-10-29 58 views
0

我想要做的是一個方法,可以如何覆蓋實例/具體類的方法運行時? (如反射,CGLIB)

  • 產生X類(一類變量ARG通過)和
  • 覆蓋它的一些實例的方法

更具體地說,父類XI要覆蓋包含

  • 不包含默認構造函數(例如,使用ARGS所有構造函數)
  • 構造函數調用同一個類

原本我以爲這是很簡單的使用反射或類似的東西內的非私有方法, 後來我發現有關於執行我的要求限制。

我認爲這是可以實現的,因爲Mockito可以執行各種方法注入運行時。
請任何人提供一些建議,謝謝。
僞代碼我圖像是這樣的:

createAndOverride(Class X) { 
    X newObj = X.newInstance(args) { 
     @override 
     methodOfX(args2) { 
      ... 
     } 
    } 
    return newObj; 
} 
  • 原始問題場景

我被用來測試其具有幾種方法調用X1.get一類(), X2.get(),X3.get()
在一些測試用例中,我需要使Xn.get()返回一些我可以控制的測試(例如null)
由於以下約束:

  • 但由於模擬工具限制JMock的1.0(我管不着:(),所以我不能只是單純地模仿Xn.get(),以返回「someSpecifiedObjects」
  • XN有沒有空的構造函數和構造函數調用非私人構件

我的解決辦法是自制XN類,並將它們傳遞到測試情況下,讓Cn.get()可以預期
代碼例如:

ClassToTest.SomeMethod(new X1() { 
    @override 
    get() { 
     return someSpecifiedObjects; 
    } 
}); 

這種事情遍佈測試用例。
因此,爲了減少重複代碼,我想構建一個方法來生成Xn實例,並使用指定的overrided方法進行測試。例如

X1 x1 = createAndOverride(X1); 

然後,這個職位的問題就來了

+0

你想「注入」一個方法到一個類? – Kiril

+0

是的,但類的類型是一個變量在運行時指定 –

+0

我想你應該告訴我們更多關於最終結果應該是什麼,因爲它看起來太複雜了。也許有一種更簡單的方法可以在運行時無需「注入」方法來實現你想做的事情。 – Kiril

回答

0

因此,我認爲你需要的是一個類似的功能的C#Reflection.Emit

雖然我沒有這樣做我自己,我覺得你應該能夠使用反射/發射和動態類型創建,以實現你正在尋找的東西。但是,我仍然想提一提,如果您試圖測試不是int的「功能」,而是測試您正在測試的函數的代碼路徑,那麼您可能根本不應該測試它。例如:

SomeObjectInterface get() 
{ 
    if(_someObjectStateIsSet) 
    { 
     // Return a concrete implementation A 
     return new ConcreteImplA(); 
    } 
    else 
    { 
     // Return a concrete implementation B 
     return new ConcreteImplB(); 
    } 
} 

在這種情況下,應該有將返回null,所以你不應該需要測試null沒有代碼路徑。我不確定我是否正確理解了您的問題,尤其是您爲什麼要測試null,但請考慮以上建議並瞭解適合您的問題。

+0

感謝您的建議,似乎返回null是這種測試的關注點。也許我沒有說清楚,null只是一個測試類的代碼路徑,它說if(Xn.get()== null){...}。 :) –

+0

@Jim,好吧,那麼發射功能不足以做你想做的? – Kiril

1

你在尋找類似javassist?您可以在運行時測試代碼並注入您的方法。我個人儘量避免字節碼操作。你能不能在你的代碼庫中使用這些覆蓋而不是在飛行中?可能是像包裝的東西?