У меня есть активность, в которой я предоставляю кнопку. Нажатие на кнопку вызывает метод в классе поставщика данных, и на основе возвращаемого значения метода я вношу изменения в пользовательский интерфейс. Теперь я хочу написать инструментальный тест, в котором я выполняю click()
на кнопке, но избегаю фактического вызова метода в классе поставщика данных. Вместо этого я хочу вернуть желаемое значение из метода, а затем проверить, был ли соответствующим образом изменен пользовательский интерфейс.
Моя активность
@Override
public void onCreate(final Bundle savedInstanceState) {
mActionButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(final View v) {
boolean result = dataProvider.getResult();
if (result) {
mSuccessTextView.setVisibility(View.VISIBLE);
}
}
});
}
Здесь при нажатии кнопки выполняется вызов DataProvider#getResult
, и результат этого метода сохраняется в result
. Если результат true
, TextView mSuccessTextView
, ранее GONE
, теперь создается VISIBLE
.
Проблема здесь в том, что DataProvider#getResult
имеет дело с множеством внешних компонентов, которые делают тестирование невозможным. Итак, что я хочу сделать, так это использовать фиктивный экземпляр DataProvider
, чтобы я мог заставить getResult
вернуть желаемое значение, а затем проверить видимость mSuccessTextView
. Это то, что я пробовал:
MyActivityTest.java
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
private DataProvider mDataProvider;
@Rule
public IntentsTestRule<MyActivity> mIntentRule =
new IntentsTestRule<>(MyClientActivity.class);
@Before
public void setUp() {
mDataProvider = mock(DataProvider.class);
}
@Test
public void testResultSuccess() {
boolean result = true;
when(mDataProvider.getResult()).thenReturn(result);
onView(withId(R.id.action_button)).perform(click());
onView(withId(R.id.success_text_view)).check((ViewAssertion) isDisplayed());
}
}
Выполнение вышеуказанного приводит к следующей ошибке:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.domain.myapp.DataProvider.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection
.
.
.
Caused by: java.lang.UnsupportedOperationException: Cannot define class using reflection
.
.
.
Caused by: java.lang.IllegalStateException: This JVM's version string does not seem to be valid: 0
.
.
.
Даже если бы вы могли издеваться над DataProvider
, это не помогло бы вам, потому что вы не внедряете его экземпляр в MyClientActivity
во время теста. Причины невозможности издеваться над DataProvider
неизвестны, пожалуйста, предоставьте класс.
Почему нельзя издеваться
DataProvider
? Говоря независимо от содержимого класса, я могу издеваться над ним во время модульного тестирования, поскольку это общедоступный и не окончательный класс. Почему я не могу издеваться над ним во время инструментального тестирования?