10

onCreate が呼び出される前に Activity の参照を取得する方法。テスト中です。JUnit ルールとして ActivityTestRule を使用します。この要件の理由は、テストからアクティビティにモックを挿入したいからです。

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

3 に答える 3

19

ドキュメントによると、ここで行っていることは間違っています。

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

MyComponent myFakeComponent;

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

なぜなら、

このルールは、単一のアクティビティの機能テストを提供します。テスト中のアクティビティは、Test で注釈が付けられた各テストの前、および@Before で注釈が付けられたメソッドの前に起動されます。 テストが完了し、After アノテーションが付けられたメソッドが終了した後に終了します。テストの期間中、アクティビティを直接操作できます。

でも!

protected void beforeActivityLaunched ()

アクティビティを作成して起動する前に実行する必要があるコードを実行するには、このメソッドをオーバーライドします。このメソッドは、@Before で注釈が付けられたメソッドを含め、各テスト メソッドの前に呼び出されます。

したがって、MainActivityComponentアクティビティの外側の初期化をモック可能な場所に移動すると、メインのアクティビティが作成される前に、それをいじることができます。

編集:

別の可能な解決策は、リンクに従ってアクティビティを遅延して開始することです。

@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();
}
于 2016-01-14T15:41:48.260 に答える
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() {
        //...
    }


}
于 2016-10-14T08:16:35.167 に答える
0

このコードは完成していますか? ダガー グラフを作成している様子が見えません。とにかく、私が自分のコードで行っていることは、グラフを作成し、オブジェクトに要素を注入できる Injector という静的クラスを用意することです。したがって、私のアプリケーション クラスでは、それを呼び出してグラフを作成し、他のすべてのアクティビティは既存のグラフを使用するだけです。

次に、テストで、アクティビティが作成される前に、別の方法でグラフを初期化する偽のテスト アプリケーション クラスを作成するか、単に Injector メソッドを呼び出してグラフを再作成することができます。私は ActivityTestRule に詳しくないので、このテストのライフ サイクルについてはあまり役に立ちません。

ただし、アクティビティを作成する前に必ず新しいグラフを作成し、アクティビティで既存のグラフを使用できるようにしてください。アクティビティがグラフにアクセスする方法 あまり好きではありませんが、アプリケーション クラスに (明示的なキャストを使用して) アクセスし、依存関係を注入するように要求するのに慣れています。これは、Dagger の例でも行われている方法です。

于 2015-08-04T05:53:15.477 に答える