2012-11-20 31 views
2

我想模擬TestNG測試用例中的具體類。類可能看起來像這樣(簡化的例子):如何初始化一個真實類的模擬

public class Example() { 

    private MyHello myHello; 

    public Example(MyHello myHello) { 
    this.myHello = myHello; 
    } 

    public String doSomething() { 
    return myHello.doSomethingElse(); 
    } 
} 

現在,我們需要模擬Example返回一些定義的值:

@BeforeMethod 
public void setUp() { 
    this.example = mock(Example.class); 
    when(this.example.doSomething()).thenReturn("dummyValue"); 
} 

看起來相當不錯,但實際上卻並非如此。 setup方法的最後一行調用Example實例的方法,這個實例沒有通過構造函數得到MyHello,所以我在setUp方法中得到了一個N​​PE。

有沒有辦法在創建模擬時注入MyHello或不允許Mockito調用真實實例上的方法?

編輯

問題,導致該觀測到的行爲,該doSomething()方法實際上是final。當我試圖解決這個問題時,我忽略了這一點。 And this is a known limitation with mockito anyway。所以我要麼刪除決賽或者爲這個類提取一個接口。

+0

你真的運行過你的例子嗎?它是否生產NPE? 它不應該,除非Mockito以奇怪的方式與CDI/Guice交互。 –

+0

是的,我真的碰到了NPE。它應該以這種方式工作?我想我會清理整個環境(再次),然後再試一次。 –

+0

問題解決(facepalm)。方法'doSomething()'是'final'。我忽略了這一點。這是一個衆所周知的限制(http://stackoverflow.com/a/3794448/105224) –

回答

2

看看是否使用doReturn("dummy").when(example).doSomething()這樣做。

Mockito.doReturn

,通過javadoc:

使用doReturn()在罕見的情況下,您不能使用時(對象)。 請注意,當(對象)總是建議用於存根時,因爲它是參數類型安全的並且更易讀(特別是在連續調用存根時)。

這裏是那些極少數情況下doReturn()來得心應手:

  1. 當間諜的真實對象,並呼籲間諜真正的方法帶來的副作用

    名單列表=新的LinkedList();

    List spy = spy(list); (0)拋出IndexOutOfBoundsException(該列表尚未清空) when(spy.get(0))。thenReturn(「foo」);

    //您必須使用doReturn()進行存根: doReturn(「foo」)。when(spy).get(0);

+0

此外,這將拋出空指針異常。 –

0

您可以受益於spy關鍵字,而不是mock

就我所關心的Mockito文檔而言,您可以對間諜進行部分模擬。

有關詳細說明,您可以從doc的主題13中受益。

+0

不完全 - 在我的情況下,不需要調用真正的方法。這就是間諜會做的事情。我想訓練一個模擬器,以便在方法被調用時帶有一些期望值的情況下返回一個虛擬值。 –