androidunit-testingandroid-activityandroid-junit

Unit Test onSaveInstanceState with ActivityRules


I'm trying to figure out how to test onSavedInstance using the newer AndroidJunit4 and Activity Rules.

@RunWith(AndroidJUnit4.class)
public class MyViewActivityTest{

    @Rule
    public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

    @Rule
    public ActivityTestRule<MyViewActivity> mActivityRule = new ActivityTestRule<>(MyViewActivity.class);

    @UiThreadTest
    @Test
    public void testOnSavedIntanceState() {
        uiThreadTestRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Intent in = new Intent();
                MyViewActivity activity = mActivityRule.launchActivity(in);
                activity.finish();
                activity.recreate();
            }
        });
    }

I get an error not sure if I am barking up the right tree.

java.lang.IllegalStateException: Must be called from main thread at android.app.Activity.recreate(Activity.java:4620)


Solution

  • You should be able to run the test with the annotation @UiThreadTest. It works for every test rule that extends UiThreadTestRule. In this case ActivityTestRule happens to do just that.

    EDIT:

    @UiThreadTest
    @Test
    public void testOnUIThread() {
        // Test to run on UI thread
    }
    

    EDIT:

    I just ran it again and remembered that you can't launch the activity on the UI thread. I made this and ran it without complications.

    @RunWith(AndroidJUnit4.class)
    public class TestActivity {
       @Rule
       public ActivityTestRule<MyViewActivity> activityRule = new ActivityTestRule<>(MyViewActivity.class, true, false);
    
       @Test
       public void testOnSavedInstanceState() throws Throwable {
           activityRule.launchActivity(new Intent());
    
           final Activity activity = activityRule.getActivity();
    
           activityRule.runOnUiThread(new Runnable() {
              @Override
              public void run() {
                 activity.finish();
                 activity.recreate();
              }
           });
      }