Тестирование, что активность называется setResult

Я пишу тесты для активности (мой тестовый класс расширяет ActivityInstrumentationTestCase2), у меня есть некоторые базовые тесты, написанные и работающие нормально.

Однако моя активность, когда она завершается, возвращает дополнительные данные вызывающей активности через setResult (resultcode, Intent i). Что я хотел бы сделать с помощью инструментария, чтобы завершить свою деятельность, а затем проверить, что она передала в вызове setResult.

Есть ли какие-то рамки для этого? я еще ничего не смог найти, один подход заключался бы в подклассе класса активности и переопределении setResult, чтобы он запомнил и разоблачил то, что было передано setResult (получается, что setResult является окончательным, поэтому вы не можете этого сделать), кажется, что должен быть лучший способ.

Ответы

Ответ 1

Как я ответил в другом ксиоме, вы также можете использовать Robolectric и затенять тестируемую активность. Затем 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());
}

Для Robolectric 3+ замените

ShadowActivity shadowActivity = Robolectric.shadowOf(mActivity);

с

ShadowActivity shadow = Shadows.shadowOf(activity);

Ответ 2

См. мой ответ из другого аналогичного вопроса:

Вы можете использовать отражение и захватывать значения непосредственно из 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   private fields for mResultCode or mResultData.  Time to update the reflection code.", e);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

Ответ 3

Другим подходом было бы использование современной фальсификации, такой как jmockit - таким образом, вы можете имитировать поведение классов андроида без эмулятора и т.д. Вы можете увидеть его образец в моих модульных тестах: https://github.com/ko5tik/jsonserializer (предыдущие версии работали против JSON в комплекте с андроид, и фактический против GSON, но издевательская логика все еще существует)