2015-08-21 86 views
2

我想存儲一個存儲庫類來測試另一個具有存儲庫的類(Holder類)。存儲庫接口支持CRUD操作,並且有很多方法,但是我對Holder類的單元測試只需要調用其中的兩個。該倉庫接口:Mockito:如何在調用時使用void方法來運行一些代碼

public interface IRepo { 
    public void remove(String... sarr); 

    public void add(String... sarr); 

    //Lots of other methods I don't need now 
} 

我希望創建一個可存儲的情況下,僅addremove定義邏輯,並提供檢查什麼叫添加和刪除後存儲在其上的一種手段儲存庫模擬。

如果我做的:

IRepo repoMock = mock(IRepo.class); 

然後,我有一個愚蠢的對象,做每一種方法罷了。沒關係,現在我只需要定義添加和刪除行爲。

我可以創建一個Set<String>並僅存在這兩個方法來處理該集合。然後,我會實例化一個擁有IRepo的持有者,注入部分殘留的模擬物,並且在對持有者進行鍛鍊之後,檢查該集合以驗證它包含它應該包含的內容。

我已經成功地部分存根使用過時的方法stubVoidremove一個void方法:

Set<String> mySet = new HashSet<>(); 
stubVoid(repoMock).toAnswer(new Answer<Void>() { 

    @Override 
    public Void answer(InvocationOnMock invocation) throws Throwable { 
     Object[] args = invocation.getArguments(); 
     String[] stringsToDelete = (String[]) args[0]; 
     mySet.removeAll(Arrays.asList(stringsToDelete)); 
     return null; 
    } 
}).on().remove(Matchers.<String>anyVararg()); 

但已被棄用,它並不比創造IRepo部分實現好得多。有沒有更好的辦法?

注:Java 7只回答請,這應該運行在Android。

回答

6

您可以使用

Mockito.doAnswer(new Answer<Void>() { 
     @Override 
     public Void answer(InvocationOnMock invocation) throws Throwable { 
      //DO SOMETHING 
      return null; 
     } 
    }).when(...).remove(Matchers.<String>anyVararg()); 

從的Javadoc:

使用doAnswer()當你想存在一個void方法時使用通用的 答案。

由於編譯器不喜歡括號內的void方法,因此需要使用與Mockito.when(對象) 不同的方法來創建stubbing void ...

例子:

doAnswer(new Answer() { 
    public Object answer(InvocationOnMock invocation) { 
     Object[] args = invocation.getArguments(); 
     Mock mock = invocation.getMock(); 
     return null; 
    }}).when(mock).someMethod(); 

見javadoc的例子爲

的Mockito
+0

有趣的怎麼沒有'doSomething'接受,而不必砍一個空白回答一個Runnable。我的使用案例到目前爲止是否被提取,它不應該在Mockito的API中? –

+0

我懷疑有沒有滿足所有用戶的圖書館。 Mockito幾乎可以很容易地擴展(見我的答案)。順便說一下,R​​unnable在你的例子中不起作用,因爲你需要調用參數。 – Ruben

+0

解決了我試圖通過測試中途強制更改某些數據的問題,謝謝! –

2

假設你有

public class IFace { 
    public void yourMethod() {    
    } 
} 

然後嘲笑它,你需要

IFace mock = Mockito.mock(IFace.class); 
    Mockito.doAnswer(new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocationOnMock) throws Throwable { 
      //PUT YOUR CODE HERE 
      return null; 
     } 
    }).when(mock).yourMethod(); 
0

如果你真的不你的實現Answer喜歡return null,您可以創建自己的答案實現委託給一個無效的方法:

public abstract class DoesSomethingAnswer implements Answer<Void> { 

    @Override 
    public Void answer(InvocationOnMock invocation) throws Throwable { 
     doSomething(invocation); 
     return null; 
    } 

    protected abstract void doSomething(InvocationOnMock invocation);  
} 

然後你的測試有一行少:

Set<String> mySet = new HashSet<>(); 
    Mockito.doAnswer(new DoesSomethingAnswer() { 
     @Override 
     protected void doSomething(InvocationOnMock invocation) { 
      Object[] args = invocation.getArguments(); 
      String[] stringsToDelete = (String[]) args[0]; 
      mySet.removeAll(Arrays.asList(stringsToDelete)); 
     } 
    }).when(repoMock).remove(Matchers.<String> anyVararg()); 

或者,如果你只需要在調用的參數:

public abstract class DoesSomethingAnswer implements Answer<Void> { 

    @Override 
    public Void answer(InvocationOnMock invocation) throws Throwable { 
     doSomething(invocation.getArguments()); 
     return null; 
    } 

    protected abstract void doSomething(Object[] args); 
} 
相關問題