Probar ese botón inicia una actividad con Robolectric


Hola tengo el siguiente código:

@RunWith(Test9Runner.class)
public class MainActivityTest 
{
    private MainActivity activity;
    private Button pressMeButton;

    @Before
    public void setUp() throws Exception 
    {
        activity = new MainActivity();
        activity.onCreate(null);
        pressMeButton = (Button) activity.findViewById(R.id.button1);
    }

    @Test
    public void shouldUpdateResultsWhenButtonIsClicked() throws Exception 
    {
        pressMeButton.performClick();
        ShadowActivity shadowActivity = shadowOf(activity);
        Intent intent = shadowActivity.getResultIntent();
        System.out.print(intent.toString());
    }
}

Pero no tengo idea de cómo probar que presionando pressMeButton comenzó una nueva Actividad. En realidad lo hace, pero ¿cómo escribir la prueba de unidad Robolectric correcta para este hecho?

Author: Vladimir Ivanov, 2011-05-05

7 answers

Use Robolectric StartedMatcher

@RunWith(Test9Runner.class) 
public class MainActivityTest  {
    private MainActivity activity;
    private Button pressMeButton;

    @Before
    public void setUp() throws Exception 
    {
        activity = new MainActivity();
        activity.onCreate(null);
        pressMeButton = (Button) activity.findViewById(R.id.button1);
    }

    @Test
    public void shouldStartNextActivityWhenButtonIsClicked() 
    {
        pressMeButton.performClick();
        assertThat(activity, new StartedMatcher(NextActivity.class));
    }  
}
 19
Author: Scott Bale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-20 19:58:23

En Robolectric 2.1.1 puede verificar si Intent starting new Activity se emitió de la siguiente manera.

@RunWith(RobolectricTestRunner.class)
public class MyTest {
  private ShadowActivity shadowActivity;
  private MyActivity activity;

  @Before
  public void setup() {
    activity = new MyActivity();
    shadowActivity = Robolectric.shadowOf(activity);        
  }

  @Test
  public shouldStartNewActivityWhenSomething() {
    //Perform activity startup
    //Do some action which starts second activity, for example View::performClick()
    //...
    //Check Intent
    Intent intent = shadowActivity.peekNextStartedActivityForResult().intent;
    assertThat(intent.getStringExtra(MySecondActivity.EXTRA_MESSAGE)).isEqualTo("blebleble");
    assertThat(intent.getComponent()).isEqualTo(new ComponentName(activity, MySecondActivity.class));
  }
}

Esto es similar a lo que estoy haciendo. Tenga en cuenta que crear Activity llamando a new Activity() hará que Robolectric imprima advertencias sobre la creación de actividad incorrectamente, esto probablemente se puede hacer mejor...

 22
Author: MichK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-27 07:23:48

Actualizando esto para 3.1.2 ya que las respuestas anteriores no funcionaron para mí: -

    loginButton.callOnClick();

    Intent startedIntent = shadowOf(activity).getNextStartedActivity();
    ShadowIntent shadowIntent = shadowOf(startedIntent);
    assertEquals(NextActivity.class, shadowIntent.getIntentClass()); 
 13
Author: James Neville,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-21 10:17:46

Inspirado por la respuesta de @MichK, aquí hay una prueba de ejecución completa usando la cadena de método buildActivity de Robolectric 2.2+:

@Test
public void testStartScheduleActivity() {
    HomeScreenActivity homeActivity = Robolectric.buildActivity(HomeScreenActivity.class).create().start().visible().get();
    ShadowActivity shadowHome = Robolectric.shadowOf(homeActivity);
    Button btnLaunchSchedule = (Button) homeActivity.findViewById(R.id.btnLaunchSchedule);
    Robolectric.clickOn(btnLaunchSchedule);

    assertThat(shadowHome.peekNextStartedActivityForResult().intent.getComponent(), equalTo(new ComponentName(homeActivity, ScheduleActivity.class)));
}
 7
Author: Ari Lacenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-05 19:46:46

Así es como se ve para el Robolectric 3

        // Click on the image view
    mShareLocationImageView.performClick();

    // Check the startActivityForResult for ShareUserLocationActivity has been triggered
    ShadowActivity shadowActivity = Shadows.shadowOf(mChatWindowsActivity);
    Intent intent = shadowActivity.peekNextStartedActivityForResult().intent;
    assertThat(intent).hasComponent(new ComponentName(mChatWindowsActivity, ShareUserLocationActivity.class));
 0
Author: jiahao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 13:50:18
@Before
public void setUp() throws Exception {
    mMainActivity = Robolectric.buildActivity(MainActivity.class)
            .create().start().visible().get();

    shadowActivity =Shadows.shadowOf(mMainActivity);
    hourlyButton = (Button) mMainActivity.findViewById(R.id.hourlyButton);
}
@Test
public void hourlyActivityButtonTest() throws Exception {

   Thread.sleep(5000);
    hourlyButton.performClick();
    Intent intent = shadowActivity.peekNextStartedActivityForResult().intent;
    assertThat(intent.getComponent()).isEqualTo(new ComponentName(mMainActivity, HourlyForecastActivity.class));

}
 0
Author: Steffy Joseph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-03 15:38:35

Al no haber utilizado ninguna de las pruebas unitarias en Android, no estoy seguro de si esto funcionará:

En la actividad que está iniciando, podría crear una variable estática llamada "instancia".

private static TheActivitysName instance;

En la actividad onCreate se establece la variable de instancia:

instance = this;

Y luego se crea un método estático para obtener esta variable.

public static TheActivitysName getInstance() {
    return instance;
}

En su prueba, puede probar en el Activitysname.getInstance(). Si es null, entonces la actividad no se ha iniciado. Si es diferente desde null, entonces la actividad ha sido creada.

No estoy seguro de si el código a verificar se ejecutará antes de que la actividad haya tenido tiempo de ser creada.

 -3
Author: Rasmus Øvlesen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-25 08:51:41