我目前正在开始对我的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中使用的所有其他工具。
答案 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.
}
}
}
}