Comment simuler la méthode e dans Log

Ici Utils.java est ma classe à tester et suivre est la méthode qui est appelée dans la classe UtilsTest. Même si je me moque de Log.e méthode comme indiqué ci-dessous

 @Before
  public void setUp() {
  when(Log.e(any(String.class),any(String.class))).thenReturn(any(Integer.class));
            utils = spy(new Utils());
  }

j'obtiens l'exception suivante

java.lang.RuntimeException: Method e in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details.
    at android.util.Log.e(Log.java)
    at com.xxx.demo.utils.UtilsTest.setUp(UtilsTest.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
30
demandé sur Sasikumar Murugesan 2016-04-22 10:20:24

8 réponses

Cela a fonctionné pour moi. Je n'utilise que JUnit et j'ai pu simuler le Log classe sans aucun tiers lib très facile. Il suffit de créer un fichier Log.java à l'intérieur app/src/test/java/android/util contenu:

public class Log {
    public static int d(String tag, String msg) {
        System.out.println("DEBUG: " + tag + ": " + msg);
        return 0;
    }

    public static int i(String tag, String msg) {
        System.out.println("INFO: " + tag + ": " + msg);
        return 0;
    }

    public static int w(String tag, String msg) {
        System.out.println("WARN: " + tag + ": " + msg);
        return 0;
    }

    public static int e(String tag, String msg) {
        System.out.println("ERROR: " + tag + ": " + msg);
        return 0;
    }

    // add other methods if required...
}
50
répondu Paglian 2017-11-23 19:00:38

Vous pouvez mettre ceci dans votre script gradle:

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

qui décidera si les méthodes non programmées d'android.jar devrait lancer des exceptions ou retourner des valeurs par défaut.

21
répondu Igor Ganapolsky 2017-03-15 04:45:00

en utilisant PowerMockito:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Log.class})
public class TestsToRun() {
    @Test
    public void test() {
        PowerMockito.mockStatic(Log.class);
    }
}

Et vous êtes bon pour aller. Soyez averti que PowerMockito ne se moquera pas automatiquement des méthodes statiques héritées, donc si vous voulez vous moquer d'une classe de journalisation personnalisée qui étend Log, vous devez toujours simuler Log pour les appels tels que MyCustomLog.e ().

20
répondu plátano plomo 2016-08-26 17:50:18

Utilisez PowerMockito.

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassNameOnWhichTestsAreWritten.class , Log.class})
public class TestsOnClass() {
    @Before
    public void setup() {
        PowerMockito.mockStatic(Log.class);
    }
    @Test
    public void Test_1(){

    }
    @Test
    public void Test_2(){

    }
 }
6
répondu Payal Kothari 2016-11-30 23:46:36

Mockito ne se moque pas des méthodes statiques. Utilisez PowerMockito sur le dessus. Ici en est un exemple.

2
répondu Antiohia 2017-05-23 12:02:37

en utilisant PowerMock on peut se moquer Journal.i/e/w méthodes statiques de Android logger. Bien sûr, idéalement vous devrait créer une interface de journalisation ou une façade et fournissent un moyen de se connecter à différentes sources.

C'est une solution complète de Kotlin:

import org.powermock.modules.junit4.PowerMockRunner
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest

/**
 * Logger Unit tests
 */
@RunWith(PowerMockRunner::class)
@PrepareForTest(Log::class)
class McLogTest {

    @Before
    fun beforeTest() {
        PowerMockito.mockStatic(Log::class.java)
        Mockito.`when`(Log.i(any(), any())).then {
            println(it.arguments[1] as String)
            1
        }
    }

    @Test
    fun logInfo() {
        Log.i("TAG1,", "This is a samle info log content -> 123")
    }
}

n'oubliez pas d'ajouter des dépendances dans gradle:

dependencies {
    testImplementation "junit:junit:4.12"
    testImplementation "org.mockito:mockito-core:2.15.0"
    testImplementation "io.kotlintest:kotlintest:2.0.7"
    testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.0-beta.5'
    testImplementation 'org.powermock:powermock-core:2.0.0-beta.5'
    testImplementation 'org.powermock:powermock-module-junit4:2.0.0-beta.5'
    testImplementation 'org.powermock:powermock-api-mockito2:2.0.0-beta.5'
}

Pour se moquer Log.println l'utilisation d'une méthode:

Mockito.`when`(Log.println(anyInt(), any(), any())).then {
    println(it.arguments[2] as String)
    1
}
1
répondu kosiara - Bartosz Kosarzycki 2018-09-05 06:29:15

je recommande bois pour votre enregistrement.

bien qu'il ne enregistrera rien lors de l'exécution de tests, mais il n'échoue pas vos tests inutilement comme le fait android Log class. Le bois vous donne beaucoup de contrôle pratique sur les deux debug et la construction de production de votre application.

0
répondu Tosin John 2018-09-12 15:58:14

une autre solution est D'utiliser Robolectric. Si vous voulez l'essayer, vérifier sa configuration.

dans la construction de votre module.gradle, ajouter le suivant

testImplementation "org.robolectric:robolectric:3.8"

android {
  testOptions {
    unitTests {
      includeAndroidResources = true
    }
  }
}

Et dans votre classe de test,

@RunWith(RobolectricTestRunner.class)
public class SandwichTest {
  @Before
  public void setUp() {
  }
}
-2
répondu Lipi 2018-03-29 12:02:17