2017-02-08 12 views
0

私は、次のコードで活性を有する:onCreate()でstartActivity()を呼び出す方法は?

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (mUser.getLoggedInUser() != null) { 
     startActivity(new Intent(this, MainActivity.class)); 
     finish(); 
     return; 
    } 
} 

ユーザーがログインしているのであれば、それはMainActivityを開始する必要があり、すぐに終了します。 MainActivityが実際に起動されたことを確認するための単体テストを作成したいと思います。

@Test 
public void testUserLoggedIn() { 
    Intents.init(); 
    mUser = new User(); 
    mActivityRule.launchActivity(null); 
    intended(hasComponent(MainActivity.class.getName()), times(1)); 
    Intents.release(); 
} 

mUserが依存注射を介して設定されており、期待通りの活動が動作します。私はエスプレッソとIntentsTestRuleを使用して、以下のことを試してみました。ただし、次の出力でテストが失敗します。

java.lang.RuntimeException: Could not launch intent Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=global.snappy.android/.activities.onboarding.FirstStartActivity } within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1486519735157 and now the last time the queue went idle was: 1486519735163. If these numbers are the same your activity might be hogging the event queue. 
at android.support.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:360) 
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:219) 
at global.snappy.android.activities.onboarding.FirstStartActivityTest.testUserLoggedIn(FirstStartActivityTest.java:108) 
at java.lang.reflect.Method.invoke(Native Method) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) 
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270) 
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runners.Suite.runChild(Suite.java:128) 
at org.junit.runners.Suite.runChild(Suite.java:27) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:115) 
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59) 
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262) 
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886) 

エスプレッソがテストに添付する前にアクティビティが閉じられているようです。 onCreate()finish()コールを削除しても、これは変更されません。この動作をテストする方法はありますか?エスプレッソが望ましいでしょうが、必要に応じて別のフレームワークを使用することもできます。

+0

「mActivityRule.launchActivity(null)」で同じアクティビティを2回起動していないことを確認してください。あなたのルールは3番目のコンストラクタパラメータとしてfalseを持っていますか? –

+0

はい、 'launchActivity'パラメータはfalseに設定されています:' new IntentsTestRule <>(FirstStartActivity.class、true、false) ' – Nutomic

答えて

0

私は解決策を見つけました。基本的には、IntentsTestRuleの代わりにActivityTestRuleを使用し、すべてのインテントをintending()で傍受します。次に、intended()でインテントを確認できます。

@Rule 
public ActivityTestRule<FirstStartActivity> mActivityRule = 
     new ActivityTestRule<>(FirstStartActivity.class, true, false); 

@Test 
public void testStartMainActivity() { 
    Intents.init(); 
    intending(anyOf(hasComponent(MainActivity.class.getName()), hasComponent(OnboardingActivity.class.getName()))) 
      .respondWith(new Instrumentation.ActivityResult(Activity.RESULT_CANCELED, null)); 
    // inject User instance here 
    mActivityRule.launchActivity(null); 
    intended(hasComponent(MainActivity.class.getName()), times(1)); 
    Intents.release(); 
} 
1

アクティビティには、Spyクラスを作成できます。 次に、MainActivityをパラメータとしてstartActivityが呼び出されたかどうかを確認できます。

テストフレームワークは優れていますが、時にはプレーンなコードがよく見え、柔軟性があります。

あなたのSpyクラスは、あなたのアクティビティ名がMyActivityであると仮定すると、このようになります。

public class MyActivitySpy extends MyActivity { 
    private boolean startActivityWasCalledToStartMainActivity; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public startActivity(Intent intent) { 
    if(intentWithActivityName(intent, MainActivity.class.getSimpleName())) { 
     startActivityWasCalledToStartMainActivity ; 
    } 
    } 

    private boolean intentWithActivityName(Intent intent, String activityName) { 
     activityName.equals(intent.getComponent().getClassName()); 
    } 

    public boolean wasStartActivityCalledToStartMainActivity() { 
     return startActivityWasCalledToStartMainActivity; 
    } 
} 

次に、テストは次のようになります。

@Test 
public void testUserLoggedIn() { 
    //launch MyActivitySpy instead of your real MyActivity 
    assertTrue(myActivitySpy.wasStartActivityCalledToStartMainActivity()); 
} 
+0

これは素晴らしい考えのようです。残念ながら、Androidはアクティビティを検出できないため失敗します。 'androidTest/AndroidManifest.xml'にアクティビティを追加した後も、アクティビティの解決に失敗します。あなたにはこれに対する解決策がありますか? – Nutomic

関連する問題