如何在调用onCreate之前获取Activity的引用。而它的测试。我使用ActivityTestRule作为JUnit规则。这个要求的原因是我想从测试中将Mocks注入活动。
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(){...}
}
答案 0 :(得分:17)
根据文档,你在这里做的是错误的。
@Rule
public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class);
MyComponent myFakeComponent;
@Before
public void setUp() {
MyActivity activity = intentsTestRule.getActivity();
activity.setComponent(myFakeComponent);
}
由于,
此规则提供单个活动的功能测试。 在每次测试注释之前,将启动测试中的活动 在使用@Before。注释的方法之前进行测试和 它将在测试完成和方法后终止 用After注释完成。在测试期间 你将能够直接操纵你的活动。
然而!
protected void beforeActivityLaunched ()
重写此方法以执行应运行的任何代码 在创建和启动活动之前。 在每种测试方法之前调用此方法, 包括用@Before注释的任何方法。
因此,如果将活动外的MainActivityComponent
初始化移动到可模拟的位置,那么您将能够在创建主活动之前将它修改在一起。
编辑:
另一种可能的解决方案是按照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();
}
答案 1 :(得分:1)
以下是我的示例代码:
public class TestClass {
@Rule
public ActivityTestRule<T> activityRule = new ActivityTestRule<T>(type) {
@Override
protected void beforeActivityLaunched() {
//TODO inject mocks, setup stubs etc..
}
};
}
@Before
public void before() {
activityRule.getActivity();
}
@Test
public void myTest() {
//...
}
}
答案 2 :(得分:0)
此代码是否完整?我无法看到你创建匕首图。 无论如何,我在我的代码中做的是有一个名为Injector的静态类,它为我创建图形,并且还可以将元素注入对象。因此,在我的应用程序类中,我将其称为创建图形,而所有其他活动仅使用现有图形。
然后,在测试中,您可以创建一个虚假的测试应用程序类,以不同的方式初始化图形,或者只是在创建活动之前重新创建调用Injector方法的图形。我对ActivityTestRule并不熟悉,所以我对这个测试的生命周期没什么帮助。
但是,只需确保在创建活动之前创建新图表,然后让活动使用现有图表。 活动如何访问图表?好吧,我并不喜欢它,但我们习惯于访问应用程序类(使用显式转换)并要求它为我们注入依赖项。这就是Dagger的例子也是如此。