2017-01-06 2 views
1

Ich bin gerade dabei, Unit-Test meine Android-Anwendung zu testen. Ich habe Probleme, wenn der Unit-Test-Trainingscode Log-Anweisungen enthält. Hier ist ein spezifischer Fall. Ich habe eine Klasse namens ServiceManager, die eine setSystemPause() und eine getSystemPause() Methode hat. Ich möchte nur einen einfachen Unit-Test, der diese LogikLog-Anweisung während des Komponententests

Klasse Servicemanager ausüben:

public class ServiceManager implements IServiceManager { 

    private final static String TAG = "ServiceManager"; 

    private boolean mSystemPauseStatus = false; 

    public boolean getSystemPause() { 
     Log.i ("TAG", "getSystemPause: " + mSystemPauseStatus); 
     return mSystemPauseStatus; 
    } 

    public void setSystemPause (boolean pauseStatus){ 
     Log.i ("TAG", "setSystemPause: " + pauseStatus); 
     mSystemPauseStatus = pauseStatus; 
    } 
} 

Der Unit-Test:

public class ServiceManagerTest { 

    @Test 
    public void testSystemPause() throws Exception { 
     ServiceManager serviceManager = new ServiceManager(); 

     serviceManager.setSystemPause(false); 
     assert (! serviceManager.getSystemPause()); 

     serviceManager.setSystemPause(true); 
     assert (serviceManager.getSystemPause()); 
    } 
} 

Das Problem sind die "Log.i" Aussagen in meinem Code. Das verursacht den folgenden Fehler:

java.lang.RuntimeException: Method i in android.util.Log not mocked. 

ich verstehen, was geschieht, während die Einheit android.jar Bibliothek testen, die verwendet wird, nicht die echten Code enthalten, und ich brauche diesen Anruf zu „Log.i“ zu verspotten.

Aber die Codebasis, die ich testen werde, enthält viele Log-Anweisungen. Ich möchte nicht jede Verwendung der Log-Einrichtung verspotten.

Meine Frage ist, wie Menschen Unit-Tests in Android tun, während Log-Anweisungen in ihrem Code haben. Gibt es eine andere Protokollfunktion, die ich in meinem Code anstelle der Protokollklasse verwenden kann?

las ich auch die Seite hier: https://developer.android.com/training/testing/unit-testing/local-unit-tests.html

Sie schlagen vor, dies zu tun in meiner build.gradle Datei:

android { 
    ... 
    testOptions { 
    unitTests.returnDefaultValues = true 
    } 
} 

Ich möchte nicht, dass greifen, weil ich will nur das Log erscheinen. Ich möchte alle anderen Einrichtungen, die ich in Android verwenden werde, angemessen überspielen.

Antwort

0

Aber beeinflusst die Log-Anweisung das Ergebnis Ihrer Komponententests? Problem ist, dass Log eine Android-spezifische Klasse ist und nicht als Teil eines JUnit 4-Tests verwendet werden kann, da es nicht Teil des Java JDK ist. Verwenden Sie returnDefaultValues = true, wenn Sie Log Anweisungen benötigen, um wie vorgesehen zu funktionieren, oder das Test als Connected Android Test (/androidTest-Ordner statt /test) ausführen.

Ich persönlich benutze returnDefaultValues = true wie Sie erwähnen, als Logging ist etwas, das ich normalerweise nicht interessiert, wenn Unit Testing, nur wenn ich versuche, bestimmte Bugs aufzuspüren.

0

Sie könnten ein Paket Ebene Methode in ServiceManager Klasse, die Log.i Methode ruft erstellen.

public class ServiceManager implements IServiceManager { 

private final static String TAG = "ServiceManager"; 

private boolean mSystemPauseStatus = false; 

public boolean getSystemPause() { 
    log("TAG", "getSystemPause: " + pauseStmSystemPauseStatusatus); 
    return mSystemPauseStatus; 
} 

public void setSystemPause (boolean pauseStatus){ 
    log("TAG", "setSystemPause: " + pauseStatus); 
    mSystemPauseStatus = pauseStatus; 
} 

void log(String tag, String message) { 
    Log.i (tag, message); 
} 

Dann können Sie diese Methode in ServiceManagerTest außer Kraft setzen keine Implementierung zur Verfügung zu stellen.

public class ServiceManagerTest { 

@Test 
public void testSystemPause() throws Exception { 
    ServiceManager serviceManager = createServiceManager(); 

    serviceManager.setSystemPause(false); 
    assert (! serviceManager.getSystemPause()); 

    serviceManager.setSystemPause(true); 
    assert (serviceManager.getSystemPause()); 
} 

private ServiceManager createServiceManager() { 
    return new ServiceManager() { 
    @Override 
    void log(String tag, String message) { 
     //Do nothing or you could test that this method was called. 
    } 
    } 
} 
} 
Verwandte Themen