单元测试期间的日志语句

时间:2017-01-06 16:21:41

标签: android unit-testing

我目前正在开始对我的Android应用程序进行单元测试。当单元测试练习代码中包含日志语句时,我遇到了问题。这是一个具体案例。我有一个名为ServiceManager的类,它有setSystemPause()getSystemPause()方法。我只想要一个简单的单元测试来运用那个逻辑

ServiceManager类:

 public class ServiceManager implements IServiceManager {

    private final static String TAG = "ServiceManager";

    private boolean mSystemPauseStatus = false;

    public boolean getSystemPause () {
        Log.i ("TAG", "getSystemPause: " + mSystemPauseStatus);
        return mSystemPauseStatus;
    }

    public void setSystemPause (boolean pauseStatus){
        Log.i ("TAG", "setSystemPause: " + pauseStatus);
        mSystemPauseStatus = pauseStatus;
    }
}

单元测试:

public class ServiceManagerTest {

    @Test
    public void testSystemPause() throws Exception {
        ServiceManager serviceManager = new ServiceManager();

        serviceManager.setSystemPause(false);
        assert (! serviceManager.getSystemPause());

        serviceManager.setSystemPause(true);
        assert (serviceManager.getSystemPause());
    }
}

问题是" Log.i"我的代码中的陈述。这会导致以下错误:

java.lang.RuntimeException: Method i in android.util.Log not mocked.

我理解发生了什么,在单元测试期间,使用的android.jar库不包含真实代码,我需要模拟对" Log.i"的调用。

但是我要测试的代码库包含很多Log语句。我不想模仿Log工具的每次使用。

我的问题是人们如何在Android中进行单元测试,同时在代码中使用Log语句。是否有另一个日志工具,我可以在我的代码而不是Log类中使用。

我也在这里阅读页面: https://developer.android.com/training/testing/unit-testing/local-unit-tests.html

他们建议在我的build.gradle文件中执行此操作:

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

我不想诉诸于此,因为我只想要显示日志。我想正确地模拟我将在Android中使用的所有其他工具。

2 个答案:

答案 0 :(得分:0)

但Log语句是否会影响单元测试的结果?问题是Log是特定于Android的类,并且不能用作JUnit 4测试的一部分,因为它不是Java JDK的一部分。如果您需要Log语句按预期工作,请使用Mockito模拟行为,使用returnDefaultValues = true,或将测试作为Connected Android Test/androidTest文件夹而不是{运行{1}})。

我个人使用/test正如你所提到的那样,只有当我试图追踪特定的错误时,我才会对单元测试感兴趣。

答案 1 :(得分:0)

您可以在ServiceManager类中创建一个包级别方法,该方法调用Log.i方法。

public class ServiceManager implements IServiceManager {

private final static String TAG = "ServiceManager";

private boolean mSystemPauseStatus = false;

public boolean getSystemPause () {
    log("TAG", "getSystemPause: " + pauseStmSystemPauseStatusatus);
    return mSystemPauseStatus;
}

public void setSystemPause (boolean pauseStatus){
    log("TAG", "setSystemPause: " + pauseStatus);
    mSystemPauseStatus = pauseStatus;
}

void log(String tag, String message) {
    Log.i (tag, message);
}

然后,您可以在ServiceManagerTest中覆盖此方法,不提供任何实现。

public class ServiceManagerTest {

@Test
public void testSystemPause() throws Exception {
    ServiceManager serviceManager = createServiceManager();

    serviceManager.setSystemPause(false);
    assert (! serviceManager.getSystemPause());

    serviceManager.setSystemPause(true);
    assert (serviceManager.getSystemPause());
}

private ServiceManager createServiceManager() {
  return new ServiceManager() {
     @Override
     void log(String tag, String message) {
       //Do nothing or you could test that this method was called.
     }
  }
}
}