Тестирование Android: проверьте onClickListener, используя приватный анонимный класс

Я использую Robolectric и Mockito и хочу убедиться, что асинхронная задача запущена или нет. Вот мой код:

    AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
    alert.setTitle(R.string.warning_text);
    alert.setMessage(message);
    alert.setPositiveButton(R.string.ok, yesListener);
    alert.setNegativeButton(R.string.cancel, noListener);
    alert.show();

private DialogInterface.OnClickListener yesListener = new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int i) {
        startAsyncTask();
    }
};

Вот мой тестовый пример

AlertDialog warningDialog = ShadowAlertDialog.getLatestAlertDialog();
Assert.assertTrue(warningDialog.isShowing());
warningDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
verify(mySpy).startAsyncTask();

Тест не проходит при проверке и получении ошибки "Требуется, но не вызывается". Однако метод onClick срабатывает.

Но при определении слушателя в строке, как показано ниже, это работает

AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
alert.setTitle(R.string.warning_text);
alert.setMessage(message);
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialogInterface, int i){
        startAsyncTask();
    }
});

alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialogInterface, int i){
        dialogInterface.dismiss();
    }
});
alert.show();

Кто-нибудь может сказать, в чем разница между этими двумя?

3 ответа

Кто-нибудь может сказать, в чем разница между этими двумя?

Не уверен, что это проблема, но в первой декларации у вас есть yesListener а также noListener:

alert.setPositiveButton(R.string.ok, yesListener);
alert.setNegativeButton(R.string.cancel, noListener);

в то время как слушатель щелчка назван driverOkClickListener, который, кажется, не используется:

private DialogInterface.OnClickListener driverOkClickListener = new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int i) {
        startAsyncTask();
    }
};

Parhaps вы хотели driverOkClickListener вместо yesListener?

Решение найдено!

В ваших тестах Robolectric вам нужно вызвать следующий метод послеperformClickилиcallOnClick.

Пример:

      alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick()
ShadowLooper.runUiThreadTasks()

После этого содержимоеonClickListenerкнопки Положительный и Отрицательный выполняются.

В вашем первом примере вы не set слушатель вашего диалога:

    AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
    alert.setTitle(R.string.warning_text);
    alert.setMessage(message);
    alert.setPositiveButton(R.string.ok, driverOkClickListener);
    alert.setNegativeButton(R.string.cancel, driverOkClickListener);
    alert.show();

...

private DialogInterface.OnClickListener driverOkClickListener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (which == DialogInterface.BUTTON_POSITIVE) {
            startAsyncTask();
        } else {
            dialogInterface.dismiss();
        }
    }
};
Другие вопросы по тегам