在finish()之后从活动中获得结果;在Android单元测试中

时间:2011-04-06 16:28:44

标签: java android unit-testing junit android-intent

我目前正在编写一些Android单元测试,虽然我已经按照我想要的方式完成了大部分工作,但有一件事让我感到难过。

我在测试中的活动中有以下代码:

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

我正在试图弄清楚如何使用Instrumentation(或其他)来读取活动的结果,或者在活动结束后获得意图。 有人可以帮忙吗?

4 个答案:

答案 0 :(得分: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);
  }
}

答案 1 :(得分:10)

或者您也可以使用 Robolectric 并隐藏正在测试的Activity。然后,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());
}

答案 2 :(得分:1)

您可以通过编写一个特殊活动来完成此操作,该活动的唯一目的是启动您正在测试结果的活动并保存结果以便断言正确性。

例如,您可以创建名为ResultReceiverActivity的活动。为其提供三种方法:getResultCodegetResultDatagetReceivedRequestCode,可用于验证测试活动是否返回了正确的值。您将创建一个扩展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,并且应该将该methods参数的值存储在其字段中,如下所示:

@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启动的活动,并且可以使用getIntent方法中的onCreate轻松完成此操作。在测试用例中,在调用getActivity之前调用setActivityIntent来设置使用哪个Intent来启动活动。

答案 3 :(得分:-1)

我不确定单元测试是否有所不同,但您应该能够使用onActivityResult,如下所示:StartingActivities。您只需使用startActivityForResult(intent,requestCode)启动Activity,然后使用

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

返回使用startActivityForResult的活动。