为什么运行Android本地单元测试时Log.d()不打印任何内容?

为什么运行Android本地单元测试时Log.d()不打印任何内容?,android,unit-testing,junit,Android,Unit Testing,Junit,我试图在运行Android本地单元测试时打印一些东西,但什么也没发生。怎么了我怎样才能修好它 我查阅了一些关于的文档,发现Android本地单元测试只在我机器的JVM上运行,用于运行单元测试的Android.jar文件不包含任何实际代码,因此Log.d()不打印任何内容。如果我想打印日志,我该怎么做 这是我的代码,FeedbackModelTest.java位于src/test/main目录中 package com.upward.reader.mvp.model; import androi

我试图在运行Android本地单元测试时打印一些东西,但什么也没发生。怎么了我怎样才能修好它

我查阅了一些关于的文档,发现Android本地单元测试只在我机器的JVM上运行,用于运行单元测试的Android.jar文件不包含任何实际代码,因此Log.d()不打印任何内容。如果我想打印日志,我该怎么做

这是我的代码,FeedbackModelTest.java位于src/test/main目录中

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();
        }

    });
}
package com.upper.reader.mvp.model;
导入android.util.Log;
导入com.upper.reader.mvp.bean.FeedbackBean;
导入com.upper.reader.net.RequestJSONCallback;
导入org.junit.Test;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
公共类反馈模型测试{
@试验
public void postFeedback()引发异常{
最终字符串url=”http://test.guguread.com/interface/app/user/feedback?";
Map params=新的HashMap();
参数put(“内容”、“内容”);
new FeedbackModel().postFeedback(url、参数、new RequestJSONCallback()){
@凌驾
public void onResponse(FeedbackBean结果)引发IOException{
Log.d(“TAG”,result.toString());
}
@凌驾
公共失效失效失效(例外e){
e、 printStackTrace();
}
});
}
}

来自:

用于运行单元测试的android.jar文件不包含任何实际代码——由真实设备上的android系统映像提供。相反,所有方法都会抛出异常(默认情况下)。这是为了确保您的单元测试只测试您的代码,而不依赖于Android平台的任何特定行为(您没有显式地模拟这些行为,例如使用Mockito)。如果这证明有问题,可以将下面的代码段添加到build.gradle中以更改此行为:


如果您需要在测试中包含某种形式的Android相关代码(Log.d),您可以使用诸如Robolectric之类的测试框架,该框架的设计类似于代码引用的Android.jar代码。通过将测试运行程序配置为在Robolectric中运行,并在Robolectric的配置注释中设置适当的配置标志,您可以使用其日志记录方法启用日志记录。

您应该使用标准输出,
System.out.println(“Hello StackOverflow”)
intead of
Log.x()
。然后您可以在“运行”选项卡中看到日志信息。


2017/12/16更新:如果在
运行
选项卡上看不到输出,请转到
Android监视器
选项卡以查找输出。

我建议您使用界面:

interface PlatformLog {
    fun e(tag: String, msg: String, throwable: Throwable?=null)
    fun i(tag: String, msg: String)
}
创建一个接口,例如:

单元测试中:

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")
    }
}

在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)
                }
            }
用法: 在android中

private val log: PlatformLog = AndroidPlatformLog()

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

测试中

private val log: PlatformLog = SystemPlatformLog()

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

或在两种情况下使用匕首2:

@Inject lateinit var log: PlatformLog

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

测试中

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)
}

上面的答案是正确的。但如果你想使用木材或原木,你仍然可以这样做

您可以在Logcat选项卡上搜索日志:

如果“本地单元测试”是指直接在JVM上运行测试(例如,Android Studio中的
test/
,而不是
androidTest/
),则没有LogCat,因此我不希望在任何地方看到该文本。是的,我正在JVM上运行测试,测试代码位于src/test/java floder中。您知道在这种情况下如何打印日志吗?日志打印到LogCat,我怀疑它是否会为本地单元测试运行。不确定,但是…这能回答你的问题吗?真有趣。我想知道,为什么不能用原木/木材语句自动实现这一点?
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)
}