Using PowerMock - robolectric/robolectric GitHub 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.
PowerMock
to a project which is using Robolectric
Steps to add 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;