2011-04-06 27 views
16

我目前正在編寫一些Android單元測試,雖然我得到了大部分東西以我想要的方式工作,但有一件事讓我感到很難過。完成後從活動中獲取結果();在Android單元測試中

我在我的活動下面的代碼測試:

Intent result = new Intent(); 
result.putExtra("test", testinput.getText().toString()); 
setResult(Activity.RESULT_OK, result); 
finish(); 

我試圖找出如何使用規範(或其他),能夠讀取活動的結果,或獲得在活動結束後的意圖。 任何人都可以幫忙嗎?

+0

http://stackoverflow.com/questions/4160755/testing-that-an-activity-called-setresult – 2011-04-07 04:48:19

+1

沒錯,類似的問題。在詢問之前先看過,但沒有很好的答案。 – uvesten 2011-04-07 08:47:40

+0

因爲你不能改變'setResult(int)'的實現,因此必須相信它的工作原理,那麼僅僅驗證在你的方法中調用方法是不夠的當前的活動? – 2017-12-12 20:27:30

回答

20

您可以使用反射並直接從活動中獲取值。

protected Intent assertFinishCalledWithResult(int resultCode) { 
    assertThat(isFinishCalled(), is(true)); 
    try { 
    Field f = Activity.class.getDeclaredField("mResultCode"); 
    f.setAccessible(true); 
    int actualResultCode = (Integer)f.get(getActivity()); 
    assertThat(actualResultCode, is(resultCode)); 
    f = Activity.class.getDeclaredField("mResultData"); 
    f.setAccessible(true); 
    return (Intent)f.get(getActivity()); 
    } catch (NoSuchFieldException e) { 
    throw new RuntimeException("Looks like the Android Activity class has changed it's private fields for mResultCode or mResultData. Time to update the reflection code.", e); 
    } catch (Exception e) { 
    throw new RuntimeException(e); 
    } 
} 
+0

太棒了!我在單元測試中使用這個而不是getActivity.getResultCode(),並且這個工作很完美 – coredump 2012-08-23 23:47:04

-1

我不確定它是否與單元測試不同,但您應該能夠使用onActivityResult,如下所示:StartingActivities。你剛開始用startActivityForResult(意向,requestCode)的活動,然後使用

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) 

回來,所使用startActivityForResult活動。

+0

是的,這是真的,謝謝。但是,我正在具體詢問單元測試用例。 – uvesten 2011-04-07 08:48:40

+0

您能否爲您所看到的特定問題添加更多細節? – 2011-04-07 16:31:58

1

您可以通過編寫一個特殊活動來達到這個目的,該活動的唯一目的是啓動您正在測試結果的活動,並保存結果以供您聲明正確性。

例如,您可以創建一個名爲ResultReceiverActivity的活動。給它三種方法:getResultCode,getResultDatagetReceivedRequestCode,它可以用來驗證測試的活動返回了正確的值。您將創建一個擴展爲ActivityInstrumentationTestCase2的測試用例,通用參數爲ResultReceiverActivity。調用getActivity將爲您提供活動實例。

public class ReturnedResultTest 
    extends ActivityInstrumentationTestCase2<ResultReceiverActivity> { 

    public void testReturnedResult() { 
     ResultReceiverActivity a = getActivity(); 
     assertEquals(Activity.RESULT_OK, a.getResultCode()); 
     assertEquals("myResult", a.getResultData().getStringExtra("test")); 
     assertEquals(0x9999, a.getReceivedRequestCode()); 
    } 
} 

ResultReceiverActivity需要重寫onActivityResult,當然,應該只是存儲方法參數的值在其領域,像這樣:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    this.receivedRequestCode = requestCode; 
    this.resultCode = resultCode; 
    this.resultData = data; 
} 

當然,你可能需要定製活動ResultReceiverActivity開始,並且您可以通過在其onCreate方法中使用getIntent來輕鬆完成此操作。在您的測試案例中,在調用getActivity設置用於啓動活動的Intent之前,請先調用setActivityIntent。

+0

謝謝,我會測試這個!但是,我意識到我的問題應該符合以下幾個方面:單元測試用戶輸入的活動結果。 (即,活動從屏幕獲取輸入)。易於單獨測試,可能難以進行單元測試。不知道是否所有這些都可以稱爲「單元測試」,真的... – uvesten 2011-04-14 11:38:59

7

或者你也可以使用Robolectric和被測影活動。然後,ShadowActivity爲您提供方法,以便輕鬆知道活動是否完成並檢索其結果代碼。

舉個例子,我的測試一個看起來是這樣的:

@Test 
public void testPressingFinishButtonFinishesActivity() { 
    mActivity.onCreate(null); 
    ShadowActivity shadowActivity = Robolectric.shadowOf(mActivity); 

    Button finishButton = (Button) mActivity.findViewById(R.id.finish_button); 
    finishButton.performClick(); 

    assertEquals(DummyActivity.RESULT_CUSTOM, shadowActivity.getResultCode()); 
    assertTrue(shadowActivity.isFinishing()); 
} 
相關問題