2012-06-25 41 views
5

很容易驗證Mockito中的模擬對象上發生了特定的交互(特定的方法調用),並且有verifyZeroInteractions()用於檢查根本沒有發生任何交互。假設我正在測試一個接口,如記錄器的接口,使用的方法有info(),warn(),error()等。在一個特定的場景中,我知道應該調用這些方法之一,但我並不在乎哪一個。是否有一種緊湊的方法來檢查與模擬對象的任何交互發生,而不需要指定應該調用哪一種方法?或者也許這樣的機制是不必要的,因爲測試這種「Mockito方式」會與我想象的不同?是否可以使用Mockito以緊湊的方式驗證任意交互?

回答

1

如果您可以從被測試的類中創建記錄器對象,那麼沒有理由不能編寫自己的測試實現來記錄哪些方法被執行並將其注入爲日誌接口的一部分你的測試設置。

模擬庫有很多好處,但有時會出現像您發現可能無法滿足您的需求的角落案例。

如果你寫你自己的測試這樣的實現,並測試其注入yourt測試類,那麼你可以在getCount() > 0

public class LoggerTestSupportImpl implements ILogger { 

    private int count = 0; 

    @Override 
    public int getCount() { 
     return count; 
    } 

    @Override 
    public void info(String message) { 
     count++;  
    } 

    @Override 
    public void warn(String message) { 
     count++;  
    } 
} 
+1

斷言這就是我如何迄今已測試我的課,我只是想知道Mockito是否可以讓我無需爲所有方法編寫簡單的實現。 –

+0

我會說你一直在做明智的事情米哈爾。 Mockito不支持這種測試。你唯一的選擇是按照Kevin提到的'ArgumentCaptor'路線,但是這會在你的測試類中產生很多「噪音」。 – Brad

+0

一致認爲它有點嘈雜,但大多數噪聲本地化爲聲明和Before方法,如果要在多個Test方法中使用Captor,甚至可以將Captor添加到類級聲明中(即使不訪問msgs也不需要) 。關於使用Mockito的好處是您可以訪問完整的日誌API。在你的例子中,你必須擴展你的手動模擬的功能(捕獲/檢索任意#個消息記錄等)。但是對於簡單的需求,你的方式看起來更簡單,更清潔,*和*可重用,所以這些爲您的方法增加一些優勢。 –

2

隨着log4j的,測試記錄我做以下設置:

@Mock private Appender log4jAppender; 
private Logger logger; 

@Before 
public void setup() { 
    MockitoAnnotations.initMocks(this); 

    Logger root = Logger.getRootLogger(); 
    if (!root.getAllAppenders().hasMoreElements()) { 
     // No appenders means log4j is not initialized! 
     BasicConfigurator.configure(); 
    } 
    logger = Logger.getLogger(MyClassWhichLogs.class); 
    logger.addAppender(log4jAppender); 
} 

,然後在我的測試中,我做到以下幾點:

verifyZeroInteractions(log4jAppender); 

verify(log4jAppender).doAppend(any(LoggingEvent.class); 

如果您需要測試記錄的值,您可以提供一個捕獲器:

ArgumentCaptor<LoggingEvent> logCaptor = ArgumentCaptor.forClass(LoggingEvent.class); 
verify(log4jAppender).doAppend(logCaptor.capture()); 
assertTrue(logCaptor.getValue().contains("my text to match"); 

雖然這不一定回答廣義問題(我不認爲你在找什麼存在),但它可能解決測試日誌記錄的這個特定問題。

相關問題