Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 985
IntoTheDeep Avatar asked Oct 28 '16 07:10

IntoTheDeep


People also ask

How to use mock construction with Mockito?

in the file org.mockito.plugins.MockMaker paste this text mock-maker-inline, now the mock maker is available during tests. With the mockConstruction you can mock calls made to the constructor. For example, we mock the constructor for the class Dog. The test code is inside a try with resources to limit the scope.

What is Mockito annotation in Java?

This annotation is a shorthand for the Mockito.mock () method. It's important to note that we should only use it in a test class. Unlike the mock () method, we need to enable Mockito annotations to use this annotation.

How to mock invocations to static method calls in Mockito?

As previously mentioned, since Mockito 3.4.0, we can use the Mockito.mockStatic (Class classToMock) method to mock invocations to static method calls. This method returns a MockedStatic object for our type, which is a scoped mock object.

How do I use the mockconstruction mock Maker inline?

Now the mock maker inline is available to use. With the mockConstruction you can mock calls made to the constructor. For example, we mock the constructor for the class Dog when your code calls the constructor, it returns a mock object. Keep this code in a try with resources to limit the scope, so you only mock the constructor in that test method.


2 Answers

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);
like image 130
Nkosi Avatar answered Oct 19 '22 01:10

Nkosi


This works for me while using PowerMockito.

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

Don't forget to type

@PrepareForTest({Build.VERSION.class})
like image 7
hendrickpras Avatar answered Oct 19 '22 01:10

hendrickpras