2016-08-29 47 views
1

我正在使用Mockito來模擬我正在編寫測試的同一個類中的方法。我在SO上看到了其他的答案(Mocking method in the same class),但可能我誤解了他們,因爲我遇到了問題。同類中的模擬方法

class Temp() { 

    public boolean methodA(String param) { 

     try { 

      if(methodB(param)) 
        return true; 

      return false; 
     } catch (Exception e) { 
       e.printStackTrace(); 
     } 
    } 
} 

我的測試方法:

@Test 
public void testMethodA() { 

    Temp temp = new Temp(); 
    Temp spyTemp = Mockito.spy(temp); 

    Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
    boolean status = temp.methodA("XYZ"); 

    Assert.assertEquals(true, status); 
} 

我卻因的methodB的定義被執行得到厚望打印出來。 我的理解是methodB的定義會被spyTemp嘲笑。然而,看起來並非如此。

有人可以請解釋我要去哪裏嗎?

回答

3

第一個問題是你必須使用spyTest對象來期待Mockito的一些東西。這裏和測試不一樣。 spyTemp是由Mockito對象temp包裝的。

另一個問題是,你存根只有methodB(),但試圖運行methodA()。是的,在您實施methodA()時,您可以調用methodB(),但您撥打this.methodB()而不是spyTemp.methodB()。在這裏你必須明白,只有當你在temp的實例上調用它時,嘲笑纔會起作用。它被Mockito代理包裹着,它可以接收你的呼叫,如果你重寫了一些方法,它會調用你的新實現而不是原來的。但是由於原來的方法被調用,在它裏面你對Mockito代理一無所知。所以,當你運行spyTemp.methodB()

你的「重寫」的方法將只被調用這應該工作:

Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
boolean status = spyTemp.methodB("XYZ"); 
2

您創建了一個間諜和嘲笑methodB()。那是對的!但是你在原始對象上調用了methodA()。爲了得到正確的結果調用它的間諜

boolean status = spyTemp.methodA("XYZ"); 
1

注意從的Mockito文檔中的以下內容:

的Mockito 委託調用到傳遞的真實情況,而不是 它實際上創建了一個副本的。因此,如果您保留真實實例並與其進行交互,請不要期望窺探知道這些交互及其對實際實例狀態的影響。推論是 ,當unstubbed方法被調用的間諜不上 實際情況,你不會看到真正的實例的任何影響。

這是特指你的情況。您保留對temp的引用,然後致電其methodA。 Mockito根本就不在這方面進行監視;它在間諜spyTemp。所以調用正常的methodB

請注意,您應該完全避免部分模擬新代碼。