Тестирование пользовательского интерфейса Android с использованием поддельных зависимостей - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть действие, в котором я предоставляю кнопку.Нажатие на кнопку вызывает метод в классе провайдера данных и основан на возвращаемом значении метода, в котором я делаю изменения пользовательского интерфейса.Теперь я хочу написать инструментальный тест, в котором я выполняю click() для кнопки, но избегаю фактического вызова метода в классе поставщика данных.Вместо этого я хочу вернуть требуемое значение из метода, а затем проверить, был ли соответствующим образом изменен пользовательский интерфейс.

MyActivity

@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
.
.
.

1 Ответ

0 голосов
/ 02 апреля 2019

Даже если бы вы могли насмехаться над DataProvider, это не помогло бы вам, потому что вы не вводите его экземпляр в MyClientActivity во время теста. Причины, по которым нельзя высмеивать DataProvider, неизвестны, просьба предоставить класс.

...