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