web-dev-qa-db-fra.com

Comment simuler la méthode e dans le journal

Ici, Utils.Java est ma classe à tester et la méthode suivante est appelée dans la classe UtilsTest . Même si je me moque de la méthode Log.e 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());
  }

Je reçois 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$1.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$3.run(ParentRunner.Java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:58)
    at org.junit.runners.ParentRunner$2.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)
40
user3762991

Cela a fonctionné pour moi. J'utilise uniquement JUnit et j'ai pu simuler la Log classe sans bibliothèque tierce très facile. Il suffit de créer un fichier Log.Java dans app/src/test/Java/Android/util avec le 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...
}
77
Paglian

Vous pouvez mettre ceci dans votre script gradle:

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

Cela déterminera si les méthodes non gênées depuis Android.jar doivent générer des exceptions ou renvoyer des valeurs par défaut.

23
IgorGanapolsky

Utilisation de PowerMockito :

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

Et vous êtes prêt à partir. Sachez que PowerMockito ne simulera pas automatiquement les méthodes statiques héritées. Ainsi, si vous souhaitez simuler une classe de journalisation personnalisée qui étend le journal, vous devez toujours simuler le journal d'appels tels que MyCustomLog.e ().

22
plátano plomo

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(){

    }
 }
7
Payal Kothari

En utilisant PowerMock, vous pouvez vous moquer de Log.i/e/w méthodes statiques à partir de l'enregistreur Android. Bien sûr, idéalement, vous {créez une interface de journalisation ou une façade} et fournissez un moyen de consigner vos données dans différentes sources.

C’est une solution complète chez 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 simuler la méthode Log.println, utilisez:

Mockito.`when`(Log.println(anyInt(), any(), any())).then {
    println(it.arguments[2] as String)
    1
}

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

2
Antiohia

Je recommanderais d'utiliser bois pour votre exploitation forestière. 

Bien qu'il n'enregistre rien lors de l'exécution des tests, il n'échoue pas inutilement vos tests comme le fait la classe Android Log. Timber vous donne beaucoup de contrôle sur les versions de débogage et de production de votre application.

1
Tosin John