android - 如何在测试期间调用 oncreate 之前获取 Activity 引用

标签 android mocking android-testing android-espresso junit-rule

如何在调用 onCreate 之前获取 Activity 的引用。虽然它正在接受测试。我使用 ActivityTestRule 作为 JUnit 规则。这个要求的原因是我想从测试中注入(inject)模拟到 Activity 中。

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(){...}
} 

最佳答案

根据文档,您在这里所做的是错误的。

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

MyComponent myFakeComponent;

@Before                                      
public void setUp() {                        
    MyActivity activity = intentsTestRule.getActivity();  
    activity.setComponent(myFakeComponent);
}              

因为,

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.

但是!

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.

因此,如果您将 MainActivityComponent 的初始化移动到 Activity 之外的一个可模拟的位置,那么您将能够在创建主 Activity 之前将其组合在一起。

编辑:

另一种可能的解决方案是根据 link 延迟启动 Activity .

@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();
}

关于android - 如何在测试期间调用 oncreate 之前获取 Activity 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31388847/

相关文章:

java - 在类(class)中添加广告 Admob 并从另一个 Activity/类(class)调用

android - Jumblr API 在将图像发布到 Tumblr 时给出了错误的请求

java - getPosition 已弃用 我应该改用什么?

unit-testing - MockK 的 spyk 如何覆盖构造函数?

ruby-on-rails - 如何 stub after_create 回调保存!在模型中?

android - Robolectric 和 GoogleCloudMessaging

android - 如何监控Android网络性能?

java - 在没有成员变量的情况下通过实现创建抽象类有什么意义?

android - Firebase 测试实验室不支持 coverageFile 环境变量

node.js - 嵌入在 Node.js 中的 Elasticsearch