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

发布于 2024-10-31 08:59:05 字数 323 浏览 1 评论 0 原文

我目前正在编写一些 Android 单元测试,虽然我已经让大多数事情按照我想要的方式工作,但有一件事让我有点困惑。

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

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

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

I'm currently writing some Android unit tests, and while I've gotten most things to work the way I want, one thing has left me kind of stumped.

I have the following code in my activity under test:

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

I'm trying to figure out how to use Instrumentation (or whatever) to be able to read the result of the activity, or get at the intent after the activity is finished.
Can anyone help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最舍不得你 2024-11-07 08:59:05

您可以使用反射并直接从活动中获取值。

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);
  }
}

You can use reflection and grab the values directly from the Activity.

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);
  }
}
对你再特殊 2024-11-07 08:59:05

或者您也可以使用 Robolectric 并跟踪测试中的 Activity。然后,ShadowActivity 为您提供了轻松了解 Activity 是否正在完成以及检索其结果代码的方法。

举个例子,我的一个测试如下所示:

@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());
}

Or you could also use Robolectric and shadow the Activity under test. Then, ShadowActivity provides you with methods to easily know if an Activity is finishing and for retrieving its result code.

As an example, one of my tests looks like this:

@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());
}
三五鸿雁 2024-11-07 08:59:05

您可以通过编写一个特殊的活动来做到这一点,该活动的唯一目的是启动您正在测试结果的活动并保存结果以供您断言正确性。

例如,您可以创建一个名为 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,并且应该只将该方法参数的值存储在其字段中,如下所示:

@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 之前调用 setActivityIntent 以设置使用哪个 Intent 来启动 Activity。

You can do this by writing a special activity whose only purpose is to start the activity you are testing for result and save the result for you to assert correctness on.

For example, you could create an activity named ResultReceiverActivity. Give it three methods: getResultCode, getResultData, and getReceivedRequestCode, which can be used to verify that the tested activity returned the right values. You would create a test case that extends ActivityInstrumentationTestCase2 and the generic parameter would be ResultReceiverActivity. Calling getActivity will get you the activity instance.

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 needs to override onActivityResult, of course, and should just store the values of that methods parameter in its fields, like so:

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

Of course, you may want to customize the activity that ResultReceiverActivity starts, and you can easily do that by using getIntent in its onCreate method. In your test case, call setActivityIntent before calling getActivity to set which Intent is used to start the activity.

各自安好 2024-11-07 08:59:05

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

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

在使用 startActivityForResult 的 Activity 中使用。

I'm not sure if it is different for unit tests, but you should be able to use onActivityResult as seen here: StartingActivities. You just start the Activity with startActivityForResult(intent, requestCode) and then use

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

back in the activity that used startActivityForResult.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文