2017-03-06 1 views
4

Ich möchte Informationen in Modellklassen protokollieren - nicht unbedingt für Komponententests, sondern für reale Szenarien, in denen ich versuche, zu debuggen.Wie funktioniert die Protokollierung von Android JUnit-Tests?

aber wenn ich versuche, android.util.Log Methoden, die ich die folgenden Fehler erhalten zu verwenden, wenn JUnit-Tests ausgeführt werden:

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

ich verstehen, warum dies der Fall ist, sollte ich nicht Android Framework-Code verwenden in Modellklassen, sind so konzipiert, dass sie rahmen unabhängig sind! Ich argumentiere nicht wirklich gegen den Fehler, aber ich versuche, einen Weg zu finden, um dies zu umgehen.

Ich habe eine Idee, macht das Sinn?

erstellen CustomLog Klasse in diese Richtung:

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); 
    } 
} 

Wo ILogger eine Schnittstelle mit den erforderlichen Methoden ist die Log-Funktionalität (e, d, usw. Methoden ...)

I auszuführen könnte eine ILoggerImpl erstellen, die android.util.Log Methoden verwendet, und eine MockLogger Klasse, die einfach auf System.out.println druckt und/oder nichts (oder etwas anderes!) tut.

Ich denke, das würde perfekt meinen Bedürfnissen entsprechen (ich würde meine Klasse CustomLog sehr früh im Lebenszyklus einrichten müssen, aber das ist keine große Sache).

Wenn ich jedoch jemals Bibliotheken von Drittanbietern/externen Code zu meinen Modellklassen hinzufügen musste, würde dies wahrscheinlich auf die gleiche Weise wieder aufbrechen, wenn die neuen Bibliotheken/Codes android.util.Log Methoden verwenden.

Also, gibt es ein "catch all" Typ Verhalten, das ich verwenden könnte? Was denken Sie?

+0

Sie können 'System.out.println()' verwenden, was vielleicht nicht perfekt ist, aber in den Testausgängen angezeigt wird. – zsmb13

+0

Definitiv. Ich habe das hier erklärt: "Ich könnte ein' ILoggerImpl' erstellen, das die 'android.util.Log' Methoden verwendet, und eine' MockLogger' Klasse, die einfach auf 'System.out.println' druckt und/oder nichts tut (oder noch etwas!)." - meine Frage bezieht sich auf _how_, damit das funktioniert. 'System.out.println' für Komponententests, aber' android.util.Log' für Debug/Release-Tests ohne Einheit! – Zach

+1

Oh richtig, sorry. Ich glaube, du hast das Beste gefunden, was du wirklich tun kannst. – zsmb13

Antwort

0

Eine Möglichkeit, die von Ihnen zitierte Ausnahme "Nicht verspottet" zu lösen, ist use PowerMockito to mock the Logging methods. Stattdessen PowerMockito.mockStatic(Log.class); der Aufruf wie in der verknüpften Antwort erklärt, können Sie Inspiration von this nehmen und verwenden PowerMockito zu replace()Android.util ‚s Log.v, Log.d, Log.i & Log.e mit Methoden, die System.out.println statt laufen. Dadurch können Sie die protokollierten Nachrichten im Android-Fenster "Ausführen" sehen.

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); 
} 

Haftungsausschluss: Ich bin mir nicht sicher, ob das oben genannte die idiomatische Implementierung ist.

+0

Persönlich denke ich, dies verstößt gegen das Prinzip, dass Modellcode keine Android-Abhängigkeiten haben sollte, aber sicher, dass _Would_ funktionieren würde, denke ich! – Zach

Verwandte Themen