Why Log.d() print nothing when running Android Local Unit Test?

試著忘記壹切 提交于 2020-02-21 07:48:23

问题


I'm trying to print something when running Android Local Unit Test, but nothing's happening. What's the matter? How can I fix it?

I consulted some documents on http://developer.android.com, found that Android Local Unit Test just run on my machine's JVM, the android.jar file that is used to run unit tests does not contain any actual code, so Log.d() print nothing. If i wanna print log, how can i do?

Here is my code, FeedbackModelTest.java located in src/test/main directory.

package com.upward.reader.mvp.model;

import android.util.Log;

import com.upward.reader.mvp.bean.FeedbackBean;
import com.upward.reader.net.RequestJSONCallback;

import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class FeedbackModelTest {

@Test
public void postFeedback() throws Exception {
    final String url = "http://test.guguread.com/interface/app/user/feedback?";
    Map<String, String> params = new HashMap<>();
    params.put("content", "content");
    new FeedbackModel().postFeedback(url, params, new RequestJSONCallback<FeedbackBean>() {

        @Override
        public void onResponse(FeedbackBean result) throws IOException {
            Log.d("TAG", result.toString());
        }

        @Override
        public void onFailure(Exception e) {
            e.printStackTrace();
        }

    });
}

}


回答1:


You should use standard output, System.out.println("Hello StackOverflow") intead of Log.x(). Then you can see the log info in the run tab.

2017/12/16 Update: If you can't see the output on the Run tab, go to Android Monitor tab to find the output instead.




回答2:


I suggest you to use interface:

interface PlatformLog {
    fun e(tag: String, msg: String, throwable: Throwable?=null)
    fun i(tag: String, msg: String)
}

create an interface for example:

in unit tests:

class SystemPlatformLog : PlatformLog {
    override fun i(tag: String, msg: String) {
        println("$tag : $msg")
    }

    override fun e(tag: String, msg: String, throwable: Throwable?) {
        println("$tag : $msg")
    }
}

In android

class AndroidPlatformLog : PlatformLog {
                override fun i(tag: String, msg: String) {
                    Log.i(tag, msg)
                }

                override fun e(tag: String, msg: String, throwable: Throwable?) {
                    Log.e(tag, msg, throwable)
                }
            }

Usage: In android

private val log: PlatformLog = AndroidPlatformLog()

public override fun onCreate(savedInstanceState: Bundle?) {
    log.i(TAG, "onCreate $savedInstanceState")
}

In tests

private val log: PlatformLog = SystemPlatformLog()

@Test
fun `should log in System`() {
    log.i(TAG, "called from tests")
}

OR with dagger2 in two cases:

@Inject lateinit var log: PlatformLog

public override fun onCreate(savedInstanceState: Bundle?) {
    log.i(TAG, "onCreate $savedInstanceState")
}

in tests

class MyTest{

@Inject lateinit var log: PlatformLog

@Before
fun setUp() {
    val component = DaggerTestComponent.builder().testModule(TestModule()).build()
        component.inject(this)
}

@Test
fun `should log in System`() {
    log.i(TAG, "called from tests")
}
@Module
open class TestModule {

    @Provides
    @Singleton
    open fun providePlatformLog(): PlatformLog {
        return SystemPlatformLog()
    }
}
@Singleton
@Component(modules = [TestModule::class])
interface TestComponent {
    fun inject(test: MyTest)
}



回答3:


From Unit Testing Support:

The android.jar file that is used to run unit tests does not contain any actual code - that is provided by the Android system image on real devices. Instead, all methods throw exceptions (by default). This is to make sure your unit tests only test your code and do not depend on any particular behaviour of the Android platform (that you have not explicitly mocked e.g. using Mockito). If that proves problematic, you can add the snippet below to your build.gradle to change this behavior:

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



回答4:


If you need to involve some form of Android-related code in your tests (which Log.d is), you can use a testing framework such as Robolectric which is designed to act like the Android.jar code that your code references. By configuring your test runner to run in Robolectric, and setting the proper config flag in robolectric's config annotations, you can enable logging using their logging methods.



来源:https://stackoverflow.com/questions/37190243/why-log-d-print-nothing-when-running-android-local-unit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!