2017-03-06 27 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

相关问题