I am new on Android and I am playing around with Robolectric for my unit tests. I am facing the following problem.
I have an activity I want to test.
MainActivity.java
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
private NavigationDrawerFragment mNavigationDrawerFragment;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
@Override
public void onNavigationDrawerItemSelected (int position) {
...
}
}
This is the test class:
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class)
public class MainActivityTests {
private ActivityController<MainActivity> controller;
private MainActivity activity;
private MainActivity spy;
@Test
public void onCreate_shouldStartNavigationDrawerFragment () {
controller = Robolectric.buildActivity(MainActivity.class);
activity = controller.get();
assertThat(activity).isNotNull();
spy = spy(activity);
spy.onCreate(null);
verify(spy).onCreate(null);
}
}
But I am getting the following exception:
java.lang.IllegalStateException: System services not available to Activities before onCreate()
at line spy.onCreate(null)
.
I have been googling for hours and I have tried several workarounds (blindly) without any success. May please anyone guide me?
Here's what did the trick for me. I use attach() before getting an activity to spy on. Tested with Robolectric 3.0
private MainActivity spyActivity;
@Before
public void setUp(){
MainActivity activity = Robolectric.buildActivity(MainActivity.class).attach().get();
spyActivity = spy(activity);
spyActivity.onCreate(null);
}
You should be driving the activity lifecycle through Robolectric. See: http://robolectric.org/activity-lifecycle/
So for your case you could do:
controller = Robolectric.buildActivity(MainActivity.class);
activity = controller.get();
assertThat(activity).isNotNull();
spy = spy(activity);
controller.create();
Note: it usually doesn't make sense to spy on the activity lifecycle when testing with Robolectric, since you're the one driving it, so you're only testing that your own method calls executed.
It means that you have to first call the onCreate() method. It has to be the very first called method.
If interested in using exactly the same controller, and work with a spy of the activity, you could modify the inner class of the controller via Reflection, check this method:
public static <T extends Activity> T getSpy(ActivityController<T> activityController) {
T spy = spy(activityController.get());
ReflectionHelpers.setField(activityController, "component", spy);
return spy;
}
The ReflectionHelper is available in Robolectric (tested on Robolectric 4.2). Then it is initialized like this:
controller = Robolectric.buildActivity(MainActivity.class);
activity = getSpy(controller.get());
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.