测试一个名为setResult的活动

时间:2010-11-12 01:03:05

标签: android unit-testing testing android-activity

我正在为一个活动编写测试(我的测试类扩展了ActivityInstrumentationTestCase2),我已经编写了一些基本测试并且工作正常。

然而,我的活动在完成后会通过setResult(结果代码,意图i)将额外数据返回给调用活动。我想使用检测做什么让我的活动完成,然后检查它在setResult调用中传递的内容。 / p>

是否提供了一些框架来实现此目的?我还没有找到任何东西,一种方法是将活动类子类化并覆盖setResult以使其记住&暴露传递给setResult的东西(事实证明setResult是最终的,所以你不能这样做),似乎应该有更好的方法。

3 个答案:

答案 0 :(得分:11)

正如我在另一个问题中回答的那样,您也可以使用 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());
}

对于Robolectric 3+替换

ShadowActivity shadowActivity = Robolectric.shadowOf(mActivity);

ShadowActivity shadow = Shadows.shadowOf(activity);

答案 1 :(得分:5)

从另一个类似的问题看我的答案:

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

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

答案 2 :(得分:1)

另一种方法是使用像jmockit这样的现代模拟框架 - 这样你就可以 模拟没有模拟器等的android类的行为。你可以在我的单元测试中看到它的样本:https://github.com/ko5tik/jsonserializer(以前的版本对着与android捆绑的JSON,对GSON实际上有效,但是模拟逻辑仍在那里)