RecyclerView adapter in unit test

How to test support library classes when running unit tests in Android Studio? According to the introduction at http://tools.android.com/tech-docs/unit-testing-support it works with standard Android classes:

Unit testing is performed on the local JVM on your development machine. Our gradle plugin will compile the source code found in src / test / java and execute it using normal gradle testing mechanisms. At run time, tests will run with a modified version of android.jar, where all final modifiers have been removed. This allows the use of popular mocking libraries such as Mockito.

However, when I try to use Mockito on a RecyclerView adapter, for example:

@Before
public void setUp() throws Exception {
    adapter = mock(MyAdapterAdapter.class);
    when(adapter.hasStableIds()).thenReturn(true);
}

Then I will get the error message:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
   It is a limitation of the mock engine.

The reason is that the support library does not provide such a jar file, "where all final modifiers have been deleted."

How do you test it? By subclassing and redefining the final methods, it is possible (which does not work like this, NO). Perhaps PowerMock?

+4
source share
1 answer

PowerMockito Solution

Step 1: Find the correct version of Mockito and PowerMock from https://code.google.com/p/powermock/wiki/MockitoUsage13 , add it to build.gradle:

testCompile 'org.powermock:powermock-module-junit4:1.6.1'
testCompile 'org.powermock:powermock-api-mockito:1.6.1'
testCompile "org.mockito:mockito-core:1.10.8"

Only update them together and in accordance with the usage page.

Step 2: Create a unit test class, prepare the target class (containing the final methods):

@RunWith(PowerMockRunner.class)
@PrepareForTest( { MyAdapterAdapter.class })
public class AdapterTrackerTest {

3: Mockito... PowerMockito:

adapter = PowerMockito.mock(PhotosHomeAlbumsAdapter.class);
PowerMockito.when(adapter.hasStableIds()).thenReturn(true);
+1

All Articles