2016-01-13 93 views
0

我想實現類似這種結構的東西。Mockito:保存模擬參數並從另一個函數返回它

主要類:

public class Connection { 

    byte[] read() throws Exception 
    { 
     // read some data 
     return data; 
    } 

    void write(byte[] data) throws Exception 
    { 
     // write some data 
    } 
} 

測試類:

public class ConnectionTest 
{ 
    private static byte[] mockData; 
    private Connection connection; 

    public Connection createMockConnection() { 
     Connection mockConnection = mock(Connection.class); 

     try { 
      doAnswer(new Answer() { 
       @Override 
       public Object answer(InvocationOnMock invocation) throws Throwable { 
        mockData = (byte[]) invocation.getArguments()[0]; 
        return mockData; 
       } 
      }).when(mockConnection).write(any(byte[].class)); 

      when(mockConnection.read()).thenReturn(mockData); 
     } catch (Exception e) {} 

     return mockConnection; 
    } 

    @Before 
    public void createConnection() throws Exception { 
     connection = createMockConnection(); 
    } 

    @After 
    public void destroyConnection() throws Exception { 
     connection = null; 
    } 

    @Test 
    public void testCallbackConnection() throws Exception { 
     byte[] data = new byte[] {1,2,3,4}; 
     connection.write(data); 

     assertArrayEquals(data, connection.read()); 
    } 

保存的值mockData並不包含實際數據緩衝區,當我磕碰write()read()方法。我怎樣才能獲得通過testCallbackConnection()函數的實際值?

謝謝!

UPDATE:

我嘲笑寫(),讀()在createMockConnection方法()函數:

doAnswer(new Answer() { 
    @Override 
    public Object answer(InvocationOnMock invocation) throws Throwable { 
     mockData = (byte[]) invocation.getArguments()[0]; 
     return mockData; 
    } 
}).when(mockConnection).write(any(byte[]. 

when(mockConnection.read()).thenReturn(mockData); 

我有真正的連接,即通過回調寫/讀功能和測試它工作正常。然後我想寫單元測試,以防我無法訪問真正的連接。在這種情況下,我創建mockConnection和存根write()(嘗試保存傳遞參數mockData字段)和read()(返回先前保存在寫入方法arg中)的方法。

我在做什麼錯?

+0

你真的模擬了'write()'和'read()'方法嗎?我沒有看到這個地方。另外,你能否清楚地告訴我們你想要測試的是什麼?如果要測試實際連接,請設置集成測試。如果你想單元測試使用連接的代碼,然後模擬連接以表現你想要的方式。 –

+1

當您調用'thenReturn(mockData)'時,mockData仍爲空,因爲沒有人在連接上調用write(),所以答案尚未執行。您需要另一個閱讀答案()。但我真的不明白你想在這裏做什麼。您正在測試Mockito,而不是您的代碼。 –

+0

我看到,當我調用存根read()方法時,mockData仍爲null。但我認爲存根方法調用只有當我嘗試調用真正的方法,即我的工作邏輯: 調用真正的方法connection.write(數據)調用存根方法mockConnection.write(數據),然後我保存傳遞的arg(數據)字段mockData。在此之後,我調用真正的方法connection.read(),調用存根方法mockConnection.read(),並返回mockData字段作爲結果。 – Andrew

回答

0

問題與Connection儘管如此,你需要和改變你如何使用第一Answer使代替thenReturn()使用thenAnswer()read()方法。基本上,您的測試代碼沒有看到對mockData參考的更新。

新代碼createMockConnection()是:

public Connection createMockConnection() { 
    Connection mockConnection = mock(Connection.class); 

    try { 
     doAnswer(new Answer<Void>() { 
      @Override 
      public Void answer(InvocationOnMock invocation) throws Throwable { 
       mockData = (byte[]) invocation.getArguments()[0]; 
       return null; 
      } 
     }).when(mockConnection).write(any(byte[].class)); 

     when(mockConnection.read()).thenAnswer(new Answer<byte[]>() { 
      @Override 
      public byte[] answer(InvocationOnMock invocation) throws Throwable { 
       return mockData; 
      } 
     }); 
    } catch (Exception e) {} 

    return mockConnection; 
} 

注意變換到第一Answer實例爲write()方法。答案的類型表示返回類型。由於write()方法不返回任何東西,你Answer實例應該Answer<Void>類型,其中因爲Void類型沒有實例您answer()方法返回null的 - 只有null可以轉換到它。

其次,您的Answer實例爲read()現在存在,而不是以前使用thenReturn()

我希望有幫助。如有需要,請給我一些進一步的問題

+0

是的,這是我的問題的決定,也謝謝! – Andrew

0

更換

when(mockConnection.read()).thenReturn(mockData); 

when(mockConnection.read()).thenAnswer(new Answer<byte[]>() { 
     @Override 
     public byte[] answer(InvocationOnMock invocation) throws Throwable { 
      return mockData; 
     } 
    }); 

現在mockData包含有效的值,即保存在write()方法和testCallbackConnection()沒有錯誤傳遞。

感謝您幫助理解Mockito存根機制。

相關問題