How to mock method e in Log

后端 未结 12 1689
忘掉有多难
忘掉有多难 2020-12-13 03:24

Here Utils.java is my class to be tested and following is the method which is called in UtilsTest class. Even if I am mocking Log.e method as shown below

 @B         


        
相关标签:
12条回答
  • 2020-12-13 04:02

    Extending the answer from kosiara for using PowerMock and Mockito in Java with JDK11 to mock the android.Log.v method with System.out.println for unit testing in Android Studio 4.0.1.

    This is a complete solution in Java:

    import android.util.Log;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    import org.mockito.invocation.InvocationOnMock;
    import org.mockito.stubbing.Answer;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    import static org.mockito.ArgumentMatchers.any;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Log.class)
    public class MyLogUnitTest {
        @Before
        public void setup() {
            // mock static Log.v call with System.out.println
            PowerMockito.mockStatic(Log.class);
            Mockito.when(Log.v(any(), any())).then(new Answer<Void>() {
                @Override
                public Void answer(InvocationOnMock invocation) throws Throwable {
                    String TAG = (String) invocation.getArguments()[0];
                    String msg = (String) invocation.getArguments()[1];
                    System.out.println(String.format("V/%s: %s", TAG, msg));
                    return null;
                }
            });
        }
    
        @Test
        public void logV() {
            Log.v("MainActivity", "onCreate() called!");
        }
    
    }
    

    Remember to add dependencies in your module build.gradle file where your unit test exists:

    dependencies {
        ...
    
        /* PowerMock android.Log for OpenJDK11 */
        def mockitoVersion =  "3.5.7"
        def powerMockVersion = "2.0.7"
        // optional libs -- Mockito framework
        testImplementation "org.mockito:mockito-core:${mockitoVersion}"
        // optional libs -- power mock
        testImplementation "org.powermock:powermock-module-junit4:${powerMockVersion}"
        testImplementation "org.powermock:powermock-api-mockito2:${powerMockVersion}"
        testImplementation "org.powermock:powermock-module-junit4-rule:${powerMockVersion}"
        testImplementation "org.powermock:powermock-module-junit4-ruleagent:${powerMockVersion}"
    }
    
    0 讨论(0)
  • 2020-12-13 04:03

    Use 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(){
    
        }
     }
    
    0 讨论(0)
  • 2020-12-13 04:03

    Mockito doesn't mock static methods. Use PowerMockito on top. Here is an example.

    0 讨论(0)
  • 2020-12-13 04:04

    This worked out for me. I'm only using JUnit and I was able to mock up the Log class without any third party lib very easy. Just create a file Log.java inside app/src/test/java/android/util with contents:

    package android.util; 
    
    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...
    }
    
    0 讨论(0)
  • 2020-12-13 04:05

    Using PowerMockito:

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

    And you're good to go. Be advised that PowerMockito will not automatically mock inherited static methods, so if you want to mock a custom logging class that extends Log, you must still mock Log for calls such as MyCustomLog.e().

    0 讨论(0)
  • 2020-12-13 04:07

    You can put this into your gradle script:

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

    That will decide whether unmocked methods from android.jar should throw exceptions or return default values.

    0 讨论(0)
提交回复
热议问题