How to get the reference of Activity before its onCreate will be called. while its under test. I use ActivityTestRule as JUnit Rule. The reason for this requirement is i want to inject Mocks into activity from tests.
public class MyActivity extends Activity{
MyComponent myComponent;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(myComponent==null){
myComponent ... //initialise dagger component
}
myComponent.inject(this);
...
}
public void setComponent(MyComponent comp){
this.myComponent = comp;
}
}
public class MyTest{
@Rule
public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class);
MyComponent myFakeComponent;
@Before
public void setUp() {
MyActivity activity = intentsTestRule.getActivity();
activity.setComponent(myFakeComponent);
}
@Test
public void testMethod1(){...}
}
As per documentation, what you're doing here is wrong.
@Rule
public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class);
MyComponent myFakeComponent;
@Before
public void setUp() {
MyActivity activity = intentsTestRule.getActivity();
activity.setComponent(myFakeComponent);
}
Because,
This rule provides functional testing of a single activity. The activity under test will be launched before each test annotated with Test and before methods annotated with @Before. It will be terminated after the test is completed and methods annotated with After are finished. During the duration of the test you will be able to manipulate your Activity directly.
However!
protected void beforeActivityLaunched ()
Override this method to execute any code that should run before your Activity is created and launched. This method is called before each test method, including any method annotated with @Before.
Therefore, if you move the initialization of the MainActivityComponent
outside the Activity to a place that is mockable, then you'll be able to tinker it together before the main activity is created.
EDIT:
Another possible solution is to lazily initiate the Activity as per link.
@Rule
public ActivityTestRule<NoteDetailActivity> mNoteDetailActivityTestRule =
new ActivityTestRule<>(NoteDetailActivity.class, true /* Initial touch mode */,
false /* Lazily launch activity */);
@Before
public void intentWithStubbedNoteId() {
// Add a note stub to the fake service api layer.
FakeNotesServiceApiImpl.addNotes(NOTE);
// Lazily start the Activity from the ActivityTestRule this time to inject the start Intent
Intent startIntent = new Intent();
startIntent.putExtra(NoteDetailActivity.EXTRA_NOTE_ID, NOTE.getId());
mNoteDetailActivityTestRule.launchActivity(startIntent);
registerIdlingResource();
}
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