Search code examples
androidtestingmockingmockitoandroid-testing

Mock Build Version with Mockito


My target is to mock Build.Version.SDK_INT with Mockito. Already tried:

final Build.VERSION buildVersion = Mockito.mock(Build.VERSION.class);
doReturn(buildVersion.getClass()).when(buildVersion).getClass();
doReturn(16).when(buildVersion.SDK_INT);

Problem is that: when requires method after mock, and .SDK_INT is not a method.


Solution

  • So far from other questions similar to this one it looks like you have to use reflection.

    Stub value of Build.VERSION.SDK_INT in Local Unit Test

    How to mock a static final variable using JUnit, EasyMock or PowerMock

    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 in this case use it like this...

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

    Another way around would be to create a class that accesses/wraps the field in a method that can be later mocked

    public interface BuildVersionAccessor {
        int getSDK_INT();
    }
    

    and then mocking that class/interface

    BuildVersionAccessor buildVersion = mock(BuildVersionAccessor.class);
    when(buildVersion.getSDK_INT()).thenReturn(16);