Mock Build Version with Mockito

为君一笑 提交于 2019-12-23 09:26:44

问题


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.


回答1:


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);



回答2:


This works for me while using PowerMockito.

Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", 16);

Don't forget to type

@PrepareForTest({Build.VERSION.class})



回答3:


In case of java.lang.ExceptionInInitializerError , use 'SuppressStaticInitializationFor' to suppress any static blocks in the class. Usable example as follows:

@SuppressStaticInitializationFor({ "android.os.Build$VERSION", "SampleClassName" )}

Be careful inner class must use $ instead of Dot .



来源:https://stackoverflow.com/questions/40300469/mock-build-version-with-mockito

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!