-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Using PowerMock
NOTE: PowerMock integration is broken in Robolectric 3.1 and 3.2, but fixed in 3.3.
Looking for an example? Check out the PowerMock
branch.
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"
@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;