Using PowerMock - robolectric/robolectric Wiki

NOTE: PowerMock integration is broken in Robolectric 3.1 and 3.2, but fixed in 3.3.

Full working example

Looking for an example? Check out the PowerMock branch.

Steps to add PowerMock to a project which is using Robolectric

Add the dependencies

Make sure to have these dependencies in addition to the standard Robolectric dependencies:

testCompile "org.powermock:powermock-module-junit4:1.6.6"
testCompile "org.powermock:powermock-module-junit4-rule:1.6.6"
testCompile "org.powermock:powermock-api-mockito:1.6.6"
testCompile "org.powermock:powermock-classloading-xstream:1.6.6"

Create your test class:

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Static.class)
public class DeckardActivityTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Test
    public void testStaticMocking() {
        PowerMockito.mockStatic(Static.class);
        Mockito.when(Static.staticMethod()).thenReturn("hello mock");

        assertTrue(Static.staticMethod().equals("hello mock"));
    }
}

The PowerMockRule is needed to start PowerMock without using it with the @RunWith annotation (we already use RobolectricTestRunner for that). @PowerMockIgnore is needed because we should not instrument the Mockito and Robolectric libraries themselves; also the Android classes are already instrumented by Robolectric.

If you use androidx.test api which recommended at Robolectric 4.0, you must add androidx.* in PowerMockIgnore block, or the test will failed with below error.

java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.

	at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
	at androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*", "androidx.*" })

If you have a problem with above approach, you can try following. Extend following class to create your Robolectric test. This project uses following configurations.

    import org.junit.runner.RunWith;
    import org.powermock.core.classloader.annotations.PowerMockIgnore;
    import org.powermock.modules.junit4.PowerMockRunner;
    import org.powermock.modules.junit4.PowerMockRunnerDelegate;
    import org.robolectric.RobolectricTestRunner;
    import org.robolectric.annotation.Config;
    
    
    /**
     * Base class extended by every Robolectric test in this project.
     * <p/>
     * You can use Powermock together with Robolectric.
     */
    @RunWith(PowerMockRunner.class)
    @PowerMockRunnerDelegate(RobolectricTestRunner.class)
    @Config(constants = BuildConfig.class,
            sdk = 21)
    @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
    public abstract class RobolectricTest {
    
    }

Do remember to use Powermock version of Mockito api, or you will get strange errors.

    import static org.powermock.api.mockito.PowerMockito.mock;
    import static org.powermock.api.mockito.PowerMockito.spy;
    import static org.powermock.api.mockito.PowerMockito.when;