2012-12-07 39 views
1

如果我在運行時打包由Mockito創建的模擬器,然後調用封裝器上的方法,則不會調用封裝的模擬器。請參閱以下內容:mockito模擬本身可以在運行時進行封裝嗎?

這是我運行測試:

import static org.mockito.Mockito.verify; 
import net.sf.cglib.proxy.Enhancer; 
import net.sf.cglib.proxy.NoOp; 
import org.junit.Test; 
import org.mockito.Mockito; 

public class MyTest { 

    @Test 
    public void mockIsCalled() { 
     final Bar bar = Mockito.mock(Bar.class); 
     final Bar wrapper = wrap(bar); 
     wrapper.foo(); 
     verify(bar).foo(); 
    } 

    @SuppressWarnings("unchecked") 
    private <T> T wrap(final T objToWrap) { 
     return (T) Enhancer.create(objToWrap.getClass(), NoOp.INSTANCE); 
    } 

} 

其中Bar是:

public interface Bar { 
    String foo(); 
} 

測試失敗並輸出我得到的是:

java.lang.NoSuchMethodError: java.lang.Object.foo()Ljava/lang/String; 
    at Bar$$EnhancerByMockitoWithCGLIB$$d2b59df8.foo(<generated>) 
    at MyTest.mockIsCalled(MyTest.java:18) 
... 

如果我將Bar變成類:

public class Bar { 

    public String foo() { 
     System.out.println("foo"); 
     return null; 
    } 

} 

的測試仍然失敗,foo被打印在控制檯上,而我得到的輸出:

Wanted but not invoked: 
bar.foo(); 
-> at MyTest.mockIsCalled(MyTest.java:20) 
Actually, there were zero interactions with this mock. 

    at MyTest.mockIsCalled(MyTest.java:20) 
... 

我很困惑。

我試圖解決的真正問題是包裝動態代理(由Mule通過組件綁定注入)以便記憶包裝動態代理上的方法調用。我想使它足夠通用,以便足夠包裝動態代理對象而不必擴展任何接口。

感謝

回答

1

你在酒吧類的情況下看到的問題,你也可以在接口版本,看到如果不是CGLIB的古怪。你不打包模擬,你正在創建一個新的對象。所以,最初的模擬從來沒有行使過。

對於使用班級版本,你有沒有試過版本create()accepts interfaces as params

我不確定我是否完全瞭解您的使用場景,但對於Mockito特定的某些內容,您可以嘗試使用由cglib創建的代理,然後使用spy()而不是嘲笑新的對象。

坦率地說,我對cglib瞭解不多,但也許你可以實現自己的Callback,它包含並代表原始對象。您可以提供CallbackEnhancer.create()而不是NoOp之一。

+0

嗯,這說得很清楚。我不打包模擬! – beluchin

相關問題