27

I have the following situation.

My activity has a fragment that depends of a Serializable Object. Here is my onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    MyObject myObj = (MyObj) getIntent().getSerializableExtra("myobj");

    if(myObj != null) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.add(R.id.container, MyFragment.newInstance(myObj));
        transaction.commit();
    }
}

But in my Espresso test I simply can't pass the intent to the activity before it's created. I tried with setActivityIntent in several ways but cant figure out how to make it work.

Here is my last attempt:

import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.test.ActivityInstrumentationTestCase2;
import org.junit.Before;

import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

public class MyActivityTest extends

     ActivityInstrumentationTestCase2<MyActivity> {

        private MyActivity activity;
        private MyObject myObj;

        public MyActivityTest() {
            super(MyActivity.class);
        }

        @Before
        protected void setUp() throws Exception {
            super.setUp();
            injectInstrumentation(InstrumentationRegistry.getInstrumentation());
            myObj = MyObject.mockObject();
            Intent i = new Intent();
            i.putExtra("myobj", myObj);
            setActivityIntent(i);

        }

        public void testName(){
            Espresso.onView(withId(R.id.name)).check(matches(withText(myObj.getObjName())));
        }

    }

I've searched a lot but nothing works. MyObject is always null in the test. I think this should be simple. What am I'm missing?

mattfred
  • 2,689
  • 1
  • 22
  • 38
rafael
  • 732
  • 1
  • 11
  • 20

4 Answers4

41

You can define the Intent to be used in this way

@RunWith(AndroidJUnit4.class)
public class MyActivityTestTest {

    private MyObject myObj;

    @Rule
    // third parameter is set to false which means the activity is not started automatically
    public ActivityTestRule<MyActivity> mActivityRule =
        new ActivityTestRule<>(MyActivity.class, false, false);


    @Test
    public void testName() {

          myObj = MyObject.mockObject();
          Intent i = new Intent();
          i.putExtra("myobj", myObj);
          mActivityRule.launchActivity(i);

         //...
    }

}
Mike Ortiz
  • 4,031
  • 4
  • 27
  • 54
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
16

You can override the ActivityTestRule.getActivityIntent() method and return a required Intent:

@Rule
public ActivityTestRule<MyActivity> mActivityRule =
        new ActivityTestRule<MyActivity>(MyActivity.class){

    @Override
    protected Intent getActivityIntent() {
        Intent intent = new Intent();
        intent.putExtra("myobj", myObj);
        return intent;
    }
};
makovkastar
  • 5,000
  • 2
  • 30
  • 50
0

It doesn't look like you are actually starting the activity anywhere.

Try calling getActivity() on the first line of testName().

This will launch the activity that you passed into the super constructor.

yogurtearl
  • 3,035
  • 18
  • 24
0

Update 2022;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import androidx.test.core.app.ActivityScenario;
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;

@RunWith(AndroidJUnit4ClassRunner.class)
public class MyTest extends Assert {

@Test
public void testMyMethod_shouldBlaBlaBla() {
    Intent myIntent = ...;
    ActivityScenario.launch(myIntent).onActivity(activity -> {
        // Tests go here, which runs on UI-Thread.
        assertTrue(false);
    });
}

}

Note that @UiThreadTest (i.e. androidx.test.annotation.UiThreadTest) is NOT used.

Top-Master
  • 7,611
  • 5
  • 39
  • 71