Log messages in android studio junit test

前端 未结 4 1709
余生分开走
余生分开走 2020-12-30 03:25

Is there a way to print out Logcat (Log.i, Log.d) messages when running a JUnit (method) test in Android Studio?

I can see System.out.print message but no logcat pri

4条回答
  •  隐瞒了意图╮
    2020-12-30 03:48

    If you still prever to go with the hacking solution (Using PowerMockito), I implemented following class to mock all android log functions.

    import android.util.Log;
    
    import org.junit.BeforeClass;
    import org.junit.runner.RunWith;
    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 java.util.HashMap;
    
    import static org.mockito.ArgumentMatchers.any;
    import static org.mockito.Matchers.anyString;
    import static org.powermock.api.mockito.PowerMockito.when;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({Log.class})
    public abstract class AndroidLogMock {
    
        private static HashMap LOG_LEVELS = new HashMap(){{
            put(Log.VERBOSE, "VERBOSE");
            put(Log.DEBUG, "DEBUG");
            put(Log.INFO, "INFO");
            put(Log.WARN, "WARN");
            put(Log.ERROR, "ERROR");
            put(Log.ASSERT, "ASSERT");
        }};
    
        private static Answer  getLogInvocation(int logLevel) {
            return (InvocationOnMock invocation) -> {
                Object[] args = invocation.getArguments();
    
                if(args.length > 1 && args.length < 3) {
                    AndroidLogMock.log(logLevel, args[0].toString(), args[1].toString());
                } else if (args.length > 1 && args[2] instanceof Throwable) { //cause I'm paranoid
                    AndroidLogMock.log(logLevel, args[0].toString(), args[1].toString(), (Throwable) args[2]);
                } else {
                    new Exception("no matching function found with correct number and/or type of arguments");
                }
    
                return null;
            };
        }
    
        private static void log(int logLevel, String tag, String message) {
            System.out.println("[" + LOG_LEVELS.get(logLevel) + "}" + " Tag:" + tag + " Msg: " + message);
        }
    
        private static void log(int logLevel, String tag, String message, Throwable throwable) {
            AndroidLogMock.log(logLevel, tag, message);
    
            System.out.println("Exception: ");
            throwable.printStackTrace();
        }
    
        @BeforeClass
        public static void setupLogMocks() {
            PowerMockito.mockStatic(Log.class);
    
            when(Log.v(anyString(), anyString())).thenAnswer(AndroidLogMock.getLogInvocation(Log.VERBOSE));
            when(Log.v(anyString(), anyString(), any(Throwable.class))).thenAnswer(AndroidLogMock.getLogInvocation(Log.VERBOSE));
    
            when(Log.d(anyString(), anyString())).thenAnswer(AndroidLogMock.getLogInvocation(Log.DEBUG));
            when(Log.d(anyString(), anyString(), any(Throwable.class))).thenAnswer(AndroidLogMock.getLogInvocation(Log.DEBUG));
    
            when(Log.i(anyString(), anyString())).thenAnswer(AndroidLogMock.getLogInvocation(Log.INFO));
            when(Log.i(anyString(), anyString(), any(Throwable.class))).thenAnswer(AndroidLogMock.getLogInvocation(Log.INFO));
    
            when(Log.w(anyString(), anyString())).thenAnswer(AndroidLogMock.getLogInvocation(Log.WARN));
            when(Log.w(anyString(), anyString(), any(Throwable.class))).thenAnswer(AndroidLogMock.getLogInvocation(Log.WARN));
    
            when(Log.e(anyString(), anyString())).thenAnswer(AndroidLogMock.getLogInvocation(Log.ERROR));
            when(Log.e(anyString(), anyString(), any(Throwable.class))).thenAnswer(AndroidLogMock.getLogInvocation(Log.ERROR));
    
            when(Log.wtf(anyString(), anyString())).thenAnswer(AndroidLogMock.getLogInvocation(Log.ASSERT));
            when(Log.wtf(anyString(), anyString(), any(Throwable.class))).thenAnswer(AndroidLogMock.getLogInvocation(Log.ASSERT));
        }
    }
    

    with imports:

    testImplementation 'junit:junit:4.12'
    testImplementation 'org.powermock:powermock-core:2.0.4'
    testImplementation 'org.powermock:powermock-module-junit4:2.0.4'
    testImplementation 'org.powermock:powermock-api-mockito2:2.0.4'
    

    for usage, extend your UnitTest class:

    public class SomeUnitTest extends AndroidLogMock {
    
        @Test
        public void testSomething() {
           Log.w("My Tag", "This is a warning");
           Log.e("My Tag", "This is an error", new Exception("Error"));
        }
    
    }
    

    But @Vasiliy is rigth, folling the OOP way is cleaner.

提交回复
热议问题