Driving the Activity Lifecycle, drivinglifecycle
Before Robolectric 2.2, most tests created Activities by calling constructors directly ,(new MyActivity()
) And then manually calling lifecycle methods suchonCreate()
. Also widely used were a set of methods inShadowActivity
(For instanceShadowActivity.callOnCreate()
) That are precursorsActivityController
.
It was a mess.ActivityController
Is a Robolectric API that changes all of this. Its goal is to mimic how Android creates your Activities and drives them through their lifecycle.
ActivityController
Is a fluent API that was introduced in Robolectric 2.0 and is now required in 2.2. In addition to calling methods likeonCreate()
, It ensures that the internal state of the Activity is consistent with the lifecycle. This includes des attaching the Activity to the Window and making system services likeLayoutInflater
Available.
// ActivityController is a smooth api available from Version 2.2. Besides calling the onCreate () method, it ensures that the status and lifecycle of actvity are consistent.
What do I do now?
You don't generally createActivityController
Directly. UseRobolectric.buildActivity()
To get started. For the most basic of tests where you simply need an initialized Activity, you can often get away with the following line:
// Generally, the activitycontroller is not directly created, but the Robolectric. buildActivity method is used. As follows:
Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().get();
This will create a new instanceMyAwesomeActivity
And call through the life cycleonCreate()
.
// This creates an activity instance and calls the oncreate () Life Cycle method.
Want to check that something happensonResume()
But notonCreate()
? Easy!
// Want to check what is done in the onresume method instead of oncreate? Easy to handle:
ActivityController controller = Robolectric.buildActivity(MyAwesomeActivity.class).create().start();Activity activity = controller.get();// assert that something hasn't happenedactivityController.resume();// assert it happened!
Similar methods are supported dedstart()
,pause()
,stop()
, Anddestroy()
. So, if you want to test the full creation lifecycle:
// Similar methods are also included instart()
,pause()
,stop()
, AndDestroy ()
Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().start().resume().visible().get();
You can simulate starting the Activity with an intent:
// Simulate the use of an intent to enable the activity
Intent intent = new Intent(Intent.ACTION_VIEW);Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).withIntent(intent).create().get();
... Or restore saved instance state:
// Or simulate opening a activity with bundle
Bundle savedInstanceState = new Bundle();Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class) .create() .restoreInstanceState(savedInstanceState) .get();
Check outActivityController
Java Docs to see more public methods available for your testing needs.
Wait, What's This
visible()
Nonsense?
// Visible () Is it nonsense?
Turns out that in a real Android app, the view hierarchy ofActivity
Is not attached toWindow
Until sometime afteronCreate()
Is called. Until this happens,Activity
'S views do not report as visible. This means you can't click on them (amongst other unexpected behavior).Activity
'S hierarchy is attached toWindow
On a device or emulatorAfteronPostResume()
OnActivity
. Rather than make assumptions about when the visibility shocould be updated, Robolectric puts the power in the developer's hands when writing tests.
// When the oncreate method calls activity, there is still no visible, which means you cannot click (or other user behavior ). Hierarche is added to the window until the onPostresume () method is called to interact with the user. Robolectric gives developers the right to change the status.
So when do you call it? Whenever you're interacting with the views insideActivity
. Methods likeRobolectric.clickOn()
Require that the view is visible and properly attached in order to function. You shoshould callvisible()
Aftercreate()
.
// When do we call it? When you want to interact with the view in the activity, you should call visible after create