2012-10-24 27 views
12

我有以下活動:測試onActivityResult()

package codeguru.startactivityforresult; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 

public class StartActivityForResult extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     this.startButton = (Button) this.findViewById(R.id.start_button); 
     this.startButton.setOnClickListener(onStart); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     int result = data.getIntExtra(StartActivityForResult.this.getString(R.string.result), -1); 
     String msg = "requestCode=" + requestCode + ", resultCode=" + resultCode + ", result=" + result; 
     Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); 
    } 

    private View.OnClickListener onStart = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Intent intent = new Intent(StartActivityForResult.this, ChildActivity.class); 

      StartActivityForResult.this.startActivityForResult(intent, R.id.child_request); 
     } 
    }; 
    private Button startButton = null; 
} 

而下面的JUnit測試:

package codeguru.startactivityforresult; 

import android.app.Activity; 
import android.app.Instrumentation; 
import android.test.ActivityInstrumentationTestCase2; 
import android.test.UiThreadTest; 
import android.widget.Button; 
import junit.framework.Assert; 

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> { 

    public StartActivityForResultTest() { 
     super(StartActivityForResult.class); 
    } 

    @Override 
    public void setUp() throws Exception { 
     super.setUp(); 

     this.setActivityInitialTouchMode(false); 

     this.activity = this.getActivity(); 
     this.startButton = (Button) this.activity.findViewById(R.id.start_button); 
    } 

    @Override 
    public void tearDown() throws Exception { 
     this.activity.finish(); 

     super.tearDown(); 
    } 

    @UiThreadTest 
    public void testStartButtonOnClick() { 
     Assert.assertTrue(this.startButton.performClick()); 

     Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, null); 
     Assert.assertNotNull(result); 

     Instrumentation.ActivityMonitor am = new Instrumentation.ActivityMonitor(ChildActivity.class.getName(), result, true); 
     Assert.assertNotNull(am); 

     Activity childActivity = this.getInstrumentation().waitForMonitorWithTimeout(am, TIME_OUT); 
     Assert.assertNotNull(childActivity); 

     Assert.fail("How do I check that StartActivityForResult correctly handles the returned result?"); 
    } 
    private Activity activity = null; 
    private Button startButton = null; 
    private static final int TIME_OUT = 5 * 1000; // 5 seconds 
} 

正如你所看到的,我想通了如何使用Instrumentation.ActivityResult來模仿的結果和Instrumentation.ActivityMonitor。我如何檢查StartActivityForResult.onActivityResult()是否正確處理了這個結果?

+0

沒有問題的鏈接,但沒有必要編寫'Assert.assert *(...)',因爲'ActivityInstrumentationTestCase2'擴展了'junit.framework.Assert':'assert *(...)'是一個實例方法,並且可以直接調用。 – Vince

+1

@Vince是的,我知道這一點。我個人更喜歡這種特殊的用法,因爲所有的'assert *()'方法都是靜態的。 –

回答

1

使用意向框架嘲笑活動結果

intending(hasComponent(DummyActivity.class.getName())).respondWith(new ActivityResult(resultCode, dataIntent)); 
rule.getActivity().startActivityForResult(new Intent(context,DummyActivity.class)); 

覈實活動結果邏輯

-2
+0

從我的代碼中可以看到,我知道如何在我的「StartActivityForResult」活動中使用'onActivityResult()'。我的問題是如何編寫JUnit測試以確保其行爲正確。 –

9

爲了測試onActivityResult()在您的測試類,所有你需要做的是:

  1. 創造出醒目ChildActivity創建和重新調整模擬的活動監視器ActivityResult。
  2. 模擬啓動ChildActivity結果的按鈕點擊。
  3. 對狀態和模擬ActivityResult做一些斷言。

樣品StartActivityForResult:

public class StartActivityForResult extends Activity { 
    private boolean activityResultIsReturned = false; 
    private String activityResult = null; 

    ... ... 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    activityResultIsReturned = true; 
    activityResult = data.getStringExtra("result"); 

    ... ... 
    } 

    ... ... 
} 

樣品StartActivityForResultTest:

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> { 
    ... ... 

    public void testOnActivityResult() { 
    // Get current Activity and check initial status: 
    StartActivityForResult myActivity = getActivity(); 
    assertFalse(myActivity.getActivityResultIsReturned()); 
    assertNull(myActivity.getActiityResult()); 

    // Mock up an ActivityResult: 
    Intent returnIntent = new Intent(); 
    returnIntent.putExtra("result", "This is the result"); 
    Instrumentation.ActivityResult activityResult = new Instrumentation.ActivityResult(Activity.RESULT_OK, returnIntent); 

    // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult: 
    Instrumentation.ActivityMonitor activityMonitor = getInstrumentation().addMonitor(ChildActivity.class.getName(), activityResult , true); 

    // Simulate a button click that start ChildActivity for result: 
    final Button button = (Button) myActivity.findViewById(com.company.R.id.open_next_activity); 
    myActivity.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
     // click button and open next activity. 
     button.performClick(); 
     } 
    }); 

    // Wait for the ActivityMonitor to be hit, Instrumentation will then return the mock ActivityResult: 
    ChildActivity childActivity = getInstrumentation().waitForMonitorWithTimeout(activityMonitor, 5); 

    // How do I check that StartActivityForResult correctly handles the returned result? 
    assertTrue(myActivity.getActivityResultIsReturned()); 
    assertEqual(myActivity.getActiityResult(), "This is the result"); 
    } 

    ... ... 
} 
+0

感謝您的建議。原帖中的我的StartActivityForResult類就是一個例子。在我的真實應用程序中,我有十幾個不同的活動要測試。其中一些活動會返回多個數據。您的測試代碼建議我必須修改每個活動的界面,以便通過爲子活動返回的每條數據添加獲取者來進行測試。我不介意編寫這段代碼的額外工作。我只是不完全滿意用僅用於測試的代碼污染生產代碼。 –

+0

這些僅僅是用來展示如何測試onActivityResult()並做一些基本斷言的樣本,取決於你的需求,在所有情況下你都不需要改變你的Activity類,例如,如果你所有的onActivityResult() UI的東西,即一個TextView,你可以直接檢查更新的文本,而無需添加任何實例變量和getter/setter方法。 – yorkw

+0

這是一個很好的觀點。正如你所說,我想大多數時候onActivityResult()都會以某種方式修改UI。 –