Тестирование на ActiveResult ()

У меня есть следующая активность:

package codeguru.startactivityforresult;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class StartActivityForResult extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        this.startButton = (Button) this.findViewById(R.id.start_button);
        this.startButton.setOnClickListener(onStart);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        int result = data.getIntExtra(StartActivityForResult.this.getString(R.string.result), -1);
        String msg = "requestCode=" + requestCode + ", resultCode=" + resultCode + ", result=" + result;
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }

    private View.OnClickListener onStart = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(StartActivityForResult.this, ChildActivity.class);

            StartActivityForResult.this.startActivityForResult(intent, R.id.child_request);
        }
    };
    private Button startButton = null;
}

И следующий тест JUnit:

package codeguru.startactivityforresult;

import android.app.Activity;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.widget.Button;
import junit.framework.Assert;

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> {

    public StartActivityForResultTest() {
        super(StartActivityForResult.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();

        this.setActivityInitialTouchMode(false);

        this.activity = this.getActivity();
        this.startButton = (Button) this.activity.findViewById(R.id.start_button);
    }

    @Override
    public void tearDown() throws Exception {
        this.activity.finish();

        super.tearDown();
    }

    @UiThreadTest
    public void testStartButtonOnClick() {
        Assert.assertTrue(this.startButton.performClick());

        Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, null);
        Assert.assertNotNull(result);

        Instrumentation.ActivityMonitor am = new Instrumentation.ActivityMonitor(ChildActivity.class.getName(), result, true);
        Assert.assertNotNull(am);

        Activity childActivity = this.getInstrumentation().waitForMonitorWithTimeout(am, TIME_OUT);
        Assert.assertNotNull(childActivity);

        Assert.fail("How do I check that StartActivityForResult correctly handles the returned result?");
    }
    private Activity activity = null;
    private Button startButton = null;
    private static final int TIME_OUT = 5 * 1000; // 5 seconds
}

Как видите, я понял, как смоделировать результат, используяInstrumentation.ActivityResult а такжеInstrumentation.ActivityMonitor, Как я могу это проверитьStartActivityForResult.onActivityResult() правильно обрабатывает этот результат?

 Vince19 июл. 2015 г., 17:22
Нет связи с вопросом, но писать не нужноAssert.assert*(...), посколькуActivityInstrumentationTestCase2 продолжаетсяjunit.framework.Assert : assert*(...) является методом экземпляра и может быть вызван напрямую.
 Code-Apprentice20 янв. 2016 г., 21:22
@ Винс Да, я знаю об этом. Я лично предпочитаю это конкретное использование, так как всеassert*() методы статичны.

Ответы на вопрос(3)

Решение Вопроса

чтобы смоделировать результат деятельности

intending(hasComponent(DummyActivity.class.getName())).respondWith(new ActivityResult(resultCode, dataIntent));
rule.getActivity().startActivityForResult(new Intent(context,DummyActivity.class));

проверить логику результата деятельности

 Code-Apprentice24 окт. 2012 г., 20:50
Как видно из моего кода, я знаю, как использоватьonActivityResult() в моемStartActivityForResult деятельность. Мой вопрос заключается в том, как написать тест JUnit, чтобы убедиться, что он ведет себя правильно.

что вам нужно сделать, это:

Создайте ActivityMonitor, который перехватывает создание ChildActivity и повторно настраивает макет ActivityResult.Имитация нажатия кнопки, которая запускает ChildActivity для результата.Сделайте некоторое утверждение о статусе и макете ActivityResult.

Пример StartActivityForResult:

public class StartActivityForResult extends Activity {
  private boolean activityResultIsReturned = false;
  private String activityResult = null;

  ... ...

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    activityResultIsReturned = true;
    activityResult = data.getStringExtra("result");

    ... ...
  }

  ... ...
}

Пример StartActivityForResultTest:

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> {
  ... ...

  public void testOnActivityResult() {
    // Get current Activity and check initial status:
    StartActivityForResult myActivity = getActivity();
    assertFalse(myActivity.getActivityResultIsReturned());
    assertNull(myActivity.getActiityResult());

    // Mock up an ActivityResult:
    Intent returnIntent = new Intent();
    returnIntent.putExtra("result", "This is the result");
    Instrumentation.ActivityResult activityResult = new Instrumentation.ActivityResult(Activity.RESULT_OK, returnIntent);

    // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
    Instrumentation.ActivityMonitor activityMonitor = getInstrumentation().addMonitor(ChildActivity.class.getName(), activityResult , true);

    // Simulate a button click that start ChildActivity for result:
    final Button button = (Button) myActivity.findViewById(com.company.R.id.open_next_activity);
    myActivity.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        // click button and open next activity.
        button.performClick();
      }
    });

    // Wait for the ActivityMonitor to be hit, Instrumentation will then return the mock ActivityResult:
    ChildActivity childActivity = getInstrumentation().waitForMonitorWithTimeout(activityMonitor, 5);

    // How do I check that StartActivityForResult correctly handles the returned result?
    assertTrue(myActivity.getActivityResultIsReturned());
    assertEqual(myActivity.getActiityResult(), "This is the result");
  }

  ... ...
}
 Code-Apprentice26 окт. 2012 г., 02:56
Неплохо подмечено. Я думаю, что большую часть времениonActivityResult() как вы сказали, изменит пользовательский интерфейс
 yorkw26 окт. 2012 г., 02:45
Это всего лишь примеры для демонстрации того, как протестировать onActivityResult () и выполнить некоторые базовые утверждения, в зависимости от ваших требований, вам не нужно изменять класс Activity во всех случаях, например, если все, что выполняет ваш onActivityResult (), это обновляет некоторый пользовательский интерфейс Например, TextView, вы можете напрямую проверять обновленный текст, не добавляя переменные экземпляра и методы getter / setter.
 Code-Apprentice26 окт. 2012 г., 02:08
Спасибо за предложения. Мой класс StartActivityForResult в исходном посте - просто пример. В моем реальном приложении у меня есть около дюжины различных действий для тестирования. Некоторые из этих действий возвращают более одного фрагмента данных. Ваш тестовый код предполагает, что мне нужно изменить интерфейс каждого действия только для тестирования, добавив геттеры для каждого фрагмента данных, возвращаемых дочерним действием. Я не против дополнительной работы по написанию этого кода. Я просто не совсем доволен загрязнением производственного кода кодом, который используется только для тестирования.

Ваш ответ на вопрос