Build.VERSION.SDK_INT在本地单元测试中的存根值

时间:2016-06-28 10:52:31

标签: android unit-testing mockito powermock

我想知道是否仍然存在Build.Version.SDK_INT的值?假设我在ClassUnderTest中有以下几行:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    //do work
}else{
    //do another work
}

我如何涵盖所有代码?

我的意思是我想用不同的SDK_INT运行两个测试来输入两个块。

使用Mockito / PowerMockito在Android 本地单元测试中是否可以使用?

由于

2 个答案:

答案 0 :(得分:23)

使用反射更改值。

 static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);

    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

    field.set(null, newValue);
 }

然后

 setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 123);

经过测试。的工作原理。

答案 1 :(得分:6)

作为反射的替代方法,您可以使用自己的类检查API,然后使用Mockito在快速JVM单元测试中测试API依赖逻辑。

示例类

import android.os.Build

class SdkChecker {

    fun deviceIsOreoOrAbove(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O

}

示例测试方法

fun createNotificationChannel(notificationManager: NotificationManager) {
    if (sdkChecker.deviceIsOreoOrAbove()) { // This sdkChecker will be mocked
        // If you target Android 8.0 (API level 26) you need a channel
        notificationManager.createNotificationChannel()
    }
}

单元测试示例

import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.verifyZeroInteractions
import com.nhaarman.mockito_kotlin.whenever

@Test
fun createNotificationChannelOnOreoOrAbove() {
    whenever(mockSdkChecker.deviceIsOreoOrAbove()).thenReturn(true)

    testedClass.createNotificationChannel(mockNotificationManager)

    verify(mockNotificationManager).createNotificationChannel()
}

@Test
fun createNotificationChannelBelowOreo() {
    whenever(mockSdkChecker.deviceIsOreoOrAbove()).thenReturn(false)

    testedClass.createNotificationChannel(mockNotificationManager)

    verifyZeroInteractions(mockNotificationManager)
}