java 在完成()之后从活动中获取结果;在 Android 单元测试中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5569830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:42:42  来源:igfitidea点击:

Get result from an activity after finish(); in an Android unit test

javaandroidunit-testingjunitandroid-intent

提问by uvesten

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.

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

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?

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

回答by Valdis R

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

回答by Edu Zamora

Or you could also use Robolectricand 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.

或者您也可以使用Robolectric隐藏被测活动。然后,ShadowActivity 为您提供了一些方法来轻松了解 Activity 是否正在完成并检索其结果代码。

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

回答by Brigham

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 ActivityInstrumentationTestCase2and the generic parameter would be ResultReceiverActivity. Calling getActivitywill get you the activity instance.

例如,您可以创建一个名为 的活动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());
    }
}

ResultReceiverActivityneeds to override onActivityResult, of course, and should just store the values of that methods parameter in its fields, like so:

ResultReceiverActivityonActivityResult当然,需要覆盖,并且应该只在其字段中存储该方法参数的值,如下所示:

@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 ResultReceiverActivitystarts, and you can easily do that by using getIntentin its onCreatemethod. In your test case, call setActivityIntent before calling getActivity to set which Intent is used to start the activity.

当然,您可能希望自定义ResultReceiverActivity启动的 Activity,您可以通过getIntent在其onCreate方法中使用来轻松实现。在您的测试案例中,在调用 getActivity 之前调用 setActivityIntent 以设置用于启动活动的 Intent。

回答by Marc Bernstein

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

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

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

back in the activity that used startActivityForResult.

回到使用 startActivityForResult 的活动中。