2011-12-30 128 views
0

說我有一個模擬的設置是這樣的:如何確定JMock模擬對象嘲笑哪個類?

JUnit4Mockery context = new JUnit4Mockery(); 
MyInterface mock = context.mock(MyInterface.class); 

後來我想檢查我的模擬對象,找出它的嘲諷什麼課:

Class mockedClass = mock.??? //would return MyInterface.class 

我沒看到什麼明顯,JMock的(2.5.1)有關如何做到這一點的javadoc - 爲mock方法簽名

<T> T mock (Class<T> typeToMock) 

在以前的版本(我看着1.2.0)Y OU將直接創建一個Mock對象,它的方法之一是

Class getMockedType() 

我試圖做到的,是使用DI裏面我的單元測試的單元測試框架。 (我使用的是Guice 3.0)。在測試中使用DI是對我正在使用的應用程序服務器/平臺的限制 - 我測試的對象是具有自己的Injector的多重子類的子類,這就是我試圖填充。

我不希望在每個測試創建AbstractModule的匿名實例,所以我試圖建立這樣的事情(這似乎將在1.2工作過):

public class MockModule extends AbstractModule { 
    private Iterable<Mock> mocks; 

    public MockModule(Iterable<Mock> mocks) { 
     this.mocks = mocks; 
    } 

    protected void configure() { 
     for (Mock mock : mocks) { 
      bind(mock.getMockedType()).toInstance(mock); 
     } 
    } 
} 

唯一缺少的是這個問題的答案(如果有的話)。

響應接受的答案

這裏是我結束了創建這個用例:

import java.lang.reflect.Proxy; 
import com.google.common.collect.Lists; 
import com.google.inject.AbstractModule; 

@SuppressWarnings({ "rawtypes", "unchecked" }) 
public class MockModule extends AbstractModule { 
    private final Iterable mocks; 

    public MockModule(Object mock) { 
     mocks = Lists.newArrayList(mock); 
    } 

    public MockModule(Iterable mocks) { 
     this.mocks = mocks; 
    } 

    protected void configure() { 
     for (Object mock : mocks) { 
      Class superclass = mock.getClass().getSuperclass(); 
      if (superclass != Object.class && superclass != Proxy.class) { 
       bind(superclass).toInstance(mock); 
       continue; 
      } 
      Class[] interfaces = mock.getClass().getInterfaces(); 
      if (interfaces.length > 0) { 
       bind(interfaces[0]).toInstance(mock); 
      } 
     } 
    } 
} 

回答

1
Class mockedClass = mock.getClass().getInterfaces()[0]; 
System.out.println("Class is " + mockedClass.getCanonicalName()); 

會打印:

Interface is MyInterface 

有可能更可靠的方式來做到這一點,但它爲這個特定的工作做好了準備JMock版本至少。

+0

謝謝!我會拭目以待,看看有人可以提出更強大的版本,但這肯定會讓我指出正確的方向。 – arootbeer 2011-12-30 09:17:30

+0

另一種方法可能是創建一個自定義的替代者,爲模擬對象添加一個額外的接口來查詢他們的類。 – 2011-12-30 09:56:34

+0

我真的很喜歡這個想法......我會研究它。 – arootbeer 2011-12-30 21:09:15

0

我不確定我是否理解你這樣做的動機。 JMock通常用於單元測試一個對象或一小羣對象,這意味着測試中的所有內容都會被刷新。 DI通常在整合或驗收測試的層面上進行測試,在鍛鍊看起來更像真實組件的東西時。

你在測試中用DI來表現什麼?

+0

我正在測試的對象在內部使用Guice'Injector'(這是它們的子類提供的服務)。我*必須*用我的嘲笑填充注射器以便測試它們。我仍然只測試對象的直接依賴關係;只是對象本身不是使用DI創建的,而是爲了我們的理智而消費DI。 – arootbeer 2011-12-30 09:22:42

+0

我還沒有看到代碼,但我的標準回答是,測試正試圖告訴你一些有關設計的內容... – 2011-12-30 16:19:35

+0

我完全同意 - 詢問我的團隊主管我有多少抱怨。但是,這些對象的創建在運行時不受我控制,因此根據我的觀點,根本無法獲得DI。 – arootbeer 2011-12-30 21:07:19