I’m trying to launch Activity
in Espresso. The thing is I want to put mocked extras to the Intent
I’m using to launch the Activity
. Here is the example.
@RunWith(AndroidJUnit4.class)
public final class NiceActivityTester
{
@Rule
public final ActivityTestRule<NiceActivity> activityRule = new ActivityTestRule<>(NiceActivity.class, true, false);
@Test
public void justStartPlease() {
NiceThing niceThing = Mockito.mock(NiceThing.class);
Mockito.when(niceThing.getName()).thenReturn("Nice!");
Intent intent = new Intent(InstrumentationRegistry.getTargetContext(), NiceActivity.class);
intent.putExtra("NICE_THING", niceThing);
activityRule.launchActivity(intent);
}
}
Unfortunately unmarshalling Parcelable
fails.
java.lang.RuntimeException: Unable to start activity ComponentInfo{app.application/app.application.activity.NiceActivity}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: NiceThing_Proxy
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: NiceThing_Proxy
at android.os.Parcel.readParcelableCreator(Parcel.java:2295)
at android.os.Parcel.readParcelable(Parcel.java:2245)
at android.os.Parcel.readValue(Parcel.java:2152)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.Bundle.getParcelable(Bundle.java:755)
at android.content.Intent.getParcelableExtra(Intent.java:5088)
at app.application.NiceActivity.getNiceThing(NiceActivity.java:40)
at app.application.NiceActivity.setUpToolbar(NiceActivity.java:30)
at app.application.NiceActivity.onCreate(NiceActivity.java:20)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.support.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:534)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
Is there any way to use mocked extras with Intent
? Maybe some best practices regarding this area?
I really don’t want to make constructors for every model I’m using, some of these classes are quite complex with a dozen of fields. Spying on the extra or the Intent
using Mockito doesn’t help.
Espresso is a testing framework that helps developers write automation test cases for user interface (UI) testing. It has been developed by Google and aims to provide a simple yet powerful framework. It allows both black-box testing as well as testing of individual components during development cycles.
Validate intents Using the intended() method, which is similar to Mockito. verify() , you can assert that a given intent has been seen. However, Espresso-Intents doesn't stub out responses to intents unless you explicitly configure it to do so. // User action that results in an external "phone" activity being launched.
Intents enables validation and stubbing of intents sent out by the application under test. An example test that simply validates an outgoing intent: public void testValidateIntentSentToPackage() { // User action that results in an external "phone" activity being launched.
Use ActivityTestRule
and override getActivityIntent
Example found here
public class MainActivityLaunchIntentTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<MainActivity>(MainActivity.class) {
@Override
protected Intent getActivityIntent() {
Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
Intent result = new Intent(targetContext, MainActivity.class);
result.putExtra("Name", "Earth");
return result;
}
};
@Test
public void shouldShowHelloEarth() {
onView(withId(R.id.main__tv_hello)).check(matches(withText("Hello Earth!")));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With