如何在测试期间调用oncreate之前获取活动引用

Raj*_*tth 9 android mocking android-testing junit-rule android-espresso

如何在调用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(){...}
} 
Run Code Online (Sandbox Code Playgroud)

Epi*_*rce 17

根据文档,你在这里做的是错误的.

@Rule
public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class);

MyComponent myFakeComponent;

@Before                                      
public void setUp() {                        
    MyActivity activity = intentsTestRule.getActivity();  
    activity.setComponent(myFakeComponent);
}              
Run Code Online (Sandbox Code Playgroud)

因为,

此规则提供单个活动的功能测试.在使用Test注释的每个测试之前以及使用@Before注释的方法之前,将启动测试中的活动. 它将在测试完成后终止,并使用After注释的方法完成.在测试期间,您将能够直接操作您的活动.

然而!

protected void beforeActivityLaunched ()
Run Code Online (Sandbox Code Playgroud)

重写此方法以执行在创建和启动Activity之前应运行的任何代码.在每个测试方法之前调用此方法,包括使用@Before注释的任何方法.

因此,如果将MainActivityComponentActivity外部的初始化移动到可模拟的位置,那么在创建主活动之前,您将能够将它修改在一起.

编辑:

另一种可能的解决方案是根据链接懒惰地启动活动.

@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();
}
Run Code Online (Sandbox Code Playgroud)


Lxu*_*Lxu 0

这段代码完整吗?我看不到你创建匕首图。不管怎样,我在代码中所做的就是有一个名为 Injector 的静态类,它为我创建图形,并且还可以将元素注入到对象中。因此,在我的应用程序类中,我称其为创建图形,而所有其他活动仅使用现有图形。

然后,在测试中,您可以创建一个假测试应用程序类,以不同的方式初始化图形,或者在创建活动之前调用 Injector 方法简单地重新创建图形。我对 ActivityTestRule 不熟悉,所以我对这个测试的生命周期帮助不大。

但只需确保在创建活动之前创建一个新图表,并让活动仅使用现有图表。活动如何访问图表?好吧,我不太喜欢它,但我们习惯于访问应用程序类(使用显式强制转换)并要求它为我们注入依赖项。Dagger 示例也是这样做的。