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
Get result from an activity after finish(); in an Android unit test
提问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 ActivityInstrumentationTestCase2
and the generic parameter would be ResultReceiverActivity
. Calling getActivity
will get you the activity instance.
例如,您可以创建一个名为 的活动ResultReceiverActivity
。给它三个方法:getResultCode
、getResultData
和getReceivedRequestCode
,它们可用于验证测试的活动是否返回了正确的值。您将创建一个扩展的测试用例,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
needs to override onActivityResult
, of course, and should just store the values of that methods parameter in its fields, like so:
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;
}
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.
当然,您可能希望自定义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 的活动中。