Sunday, July 14, 2019

Robolectric shadows can help mock final classes

PowerMock can mock final classes, but this requires rewriting them into a different classloader. In some cases, like getting a SupportMapFragment from the Google Maps SDK, PowerMock's reload leads to errors saying a something can't be cast to its own type. (The class gets loaded twice and instances are not convertible between the two.) Adding the class to @PowerMockIgnore fixes that, but then PowerMock can no longer work with it.

Fortunately, Robolectric does its own bytecode manipulation. Shadows can replace methods from Android classes. In the process of installing a shadow for a class, Robolectric seems to make it non-final. So declaring an empty shadow is sufficient to allow Mockito.mock to create mocks of it.

@Implements(GoogleMap.class)
public class ShadowGoogleMap { }

The shadow class needs to be registered either in robolectric.properties or in the shadows property of the @Config annotation on the test suite.

No comments:

Post a Comment