I am wondering if there is anyway to stub the value of Build.Version.SDK_INT
? Suppose I have the following lines in the ClassUnderTest
:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//do work
}else{
//do another work
}
How can I cover all the code ?
I mean I want to run two tests with different SDK_INT to enter both blocks.
Is it possible in android local unit tests using Mockito
/PowerMockito
?
Thanks
Change the value using reflection.
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);
}
And then
setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 123);
It is tested. Works.
Update: There is a cleaner way to do it.
Create an interface
interface BuildVersionProvider {
fun currentVersion(): Int
}
Implement the interface
class BuildVersionProviderImpl : BuildVersionProvider {
override fun currentVersion() = Build.VERSION.SDK_INT
}
Inject this class as a constructor argument through the interface whenever you want current build version. Then in the tests when creating a SUT (System Under Test) object. You can implement the interface yourself. This way of doing things may be more code but follows the SOLID principles and gives you testable code without messing with reflection and system variables.