2017-03-06 28 views
4

我想在模型類中記錄信息 - 不一定是爲了單元測試目的,而是在我嘗試調試的現實生活場景中。如何在Android JUnit測試中處理日誌記錄?

但是,如果我嘗試使用android.util.Log方法運行JUnit測試時,我得到了以下錯誤:

java.lang.RuntimeException: Method d in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details. 

我明白爲什麼發生這種情況,我不應該使用Android框架代碼模型類,被設計爲獨立於框架!我並不是真的在反對這個錯誤,但我試圖找到解決這個問題的方法。

我有一個想法,這是否有意義?

沿着這些路線創建CustomLog類:

public class CustomLog { 
    private static ILogger mLogger; 

    public static void setLogger(ILogger logger) { 
     mLogger = logger; 
    } 

    public static void e(String tag, String message) { 
     mLogger.e(tag, message); 
    } 
} 

凡​​是與所需方法的接口來執行日誌的功能(例如,d等方法...)

我可以創建一個使用android.util.Log方法的ILoggerImpl,以及僅打印到System.out.println和/或什麼也不做(或其他任何東西!)的MockLogger類。

我認爲這完全符合我的需求(我需要在生命週期的早期階段設置我的CustomLog類,但那不是什麼大問題)。但是,如果我需要將第三方庫/外部代碼添加到我的模型類,那麼如果新的庫/代碼使用android.util.Log方法,則可能會再次以相同的方式再次破壞。

那麼,是否有我可以使用的「全部捕獲」類型的行爲?你怎麼看?

+0

您可以使用'System.out.println()',這可能不完美,但會顯示在測試輸出中。當然是 – zsmb13

+0

。我在這裏解釋說:「我可以創建一個使用'android.util.Log'方法的'ILoggerImpl',以及一個'MockLogger'類,它可以簡單地輸出到'System.out.println'和/或什麼也不做(或還要別的嗎!)。」 - 我的問題是關於如何讓這個工作很好。 'System.out.println'用於單元測試,但'android.util.Log'用於調試/發佈非單元測試! – Zach

+1

噢,對不起。我認爲你找到了你能做到的最好的事情。 – zsmb13

回答

0

解決您引用的「未模擬」異常的一種方法是use PowerMockito to mock the Logging methods。與其說PowerMockito.mockStatic(Log.class);作爲鏈接的答案解釋的,你可以採取的靈感來自this,並使用PowerMockito到replace()Android.utilLog.vLog.dLog.i & Log.e與運行System.out.println代替方法。這使您可以在Android Studio的「運行」窗口中查看記錄的消息。

String[] logMethods = {"v", "d", "i", "e"}; 
InvocationHandler systemOutPrintln = new InvocationHandler() { 
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     StringBuilder messageBuilder = new StringBuilder(); 
     for (int i = 0; i < args.length; i++) { 
      String arg = args[i].toString(); 
      messageBuilder.append(arg); 
      // add separators, ASCII art, ... 
     } 
     System.out.println(messageBuilder); 
     return messageBuilder.toString().length(); 
    } 
}; 

for (String logMethod : logMethods) { 
    replace(method(Log.class, logMethod, String.class, String.class)).with(systemOutPrintln); 
    replace(method(Log.class, logMethod, String.class, String.class, Throwable.class)).with(systemOutPrintln); 
} 

聲明:我不確定上述是最習慣的實現。

+0

我個人認爲這違反了模型代碼不應該有Android依賴關係的原則,但是肯定這個_would_我認爲的工作! – Zach

相關問題