基本上,您遇到了與嘗試使用new
測試新創建的實例相同的問題; Class.newInstance
(可能正確Class.forName(foo).newInstance()
)不會傷害你,但也不幫助你。
作爲一個便箋,您的TestHandler
聽起來像一個通用的委託實現,無論如何聽起來非常有用(特別是如果您需要編寫Handler包裝器)。如果是這樣,您可能需要將其提升爲與您的生產代碼樹中的處理程序相鄰。
雖然我認識到你提到遺留代碼,但如果允許重構包含測試接縫,這將變得非常簡單。 (這裏忽略反射異常,爲了便於說明。)
public ReturnType yourMethodUnderTest(String className) {
return yourMethodUnderTest(Class.newInstance(className));
}
/** Package private for testing. */
public ReturnType yourMethodUnderTest(Handler handler) {
return yourMethodUnderTest(Class.newInstance(className));
}
你也可以提取對象的創建和測試中的替換:
/** Instance field, package-private to replace in tests. */
Function<String, Handler> instanceCreator =
(x -> (Handler) Class.forName(x).newInstance());
public ReturnType yourMethodUnderTest(String className) {
Handler handler = instanceCreator.apply(className);
// ...
}
你甚至可以只是將其解壓縮到一個方法和替換它在您的測試:
public ReturnType yourMethodUnderTest(String className) {
Handler handler = createHandler(className);
// ...
}
/** Package private for testing. */
Handler createHandler(String className) {
return Class.forName(className).newInstance();
}
@Test public void yourTest() {
// Manually replace createHandler. You could also use a Mockito spy here.
ObjectUnderTest objectUnderTest = new ObjectUnderTest() {
@Override Handler createHandler(String className) {
return mock(Handler.class);
}
}
// ...
}
邊注:即使創建的Mockito一個名爲動態類型,你幾乎肯定無法破解它並允許你的代碼按名稱創建它。這是因爲致電mock
registers the instance within Mockito's internal state。
// BAD: Unlikely to work
@Test public void yourTest() {
objectUnderTest.methodUnderTest(
mock(Handler.class).getClass().getName());
// ...
}
你究竟想要測試什麼?當您調用某個方法時,是否創建了正確的運行時類型的實例? – kai
我想驗證在新創建的對象上正在調用方法。 –