Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Testing Handler.postDelayed

I'm newbie on Android and get stuck on testing a SplashScreen, basically what I'm doing is trying to test that the splash screen stays on for 3s. this is the code for the splashScreen

@Override
protected void onStart() {
    super.onStart();

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
            startActivity(i);
            finish();
        }
    }, SPLASH_TIME_OUT);
}

And this is my approach for the test:

@Test
public void splashScreenTimerTest() throws InterruptedException {
    StopWatch timer = new StopWatch();
    timer.start();

    splashScreenActivityController.start();

    timer.stop();
    long expected = 3000L;
    assertThat(String.format("The spalash screen run for longer than expected. It should stay on for [%d] but it run for [%d]",expected,timer.getTime()),timer.getTime(),equalTo(expected));
}

I'm using Android+Robolectric for testing.

I've been googling for a couple days, I tried many things but no result at all. I try to get the UI Thread and wait for it. I tried to you scheduler to get the queue and see if there is any task there. But no result at all.

Any suggestion how can I make my test wait until the new Activity is triggered?

Thanks

like image 991
Rabel Avatar asked Jul 08 '14 21:07

Rabel


People also ask

What is Handler postDelayed in Android?

postDelayed(Runnable r, Object token, long delayMillis) Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. final void. removeCallbacks(Runnable r) Remove any pending posts of Runnable r that are in the message queue.

What is Handler removeCallbacks?

removeCallbacks simply removes those runnables who have not yet begun processing from the queue.

What is testInstrumentationRunner Android?

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // The following argument makes the Android Test Orchestrator run its. // "pm clear" command after each test invocation. This command ensures. // that the app's state is completely cleared between tests.

How do I cancel handler?

removecallback and handler = null; to cancel out the handle just to keep the code clean and make sure everything will be removed.


2 Answers

In Robolectric 3.0, they updated this API. The actual version:

ShadowLooper.runUiThreadTasksIncludingDelayedTasks();

Usage example:

public class MainActivity extends AppCompatActivity {
    ........

    public void finishGame() {
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        }, 5000);
    }
}

Test arount it:

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk=21)
public class MainActivityTest {

    @Test
    public void testFinishing() throws InterruptedException {
        MainActivity mainActivity = new MainActivity();

        assertFalse(mainActivity.isFinishing());

        mainActivity.finishGame();
        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();

        assertTrue(mainActivity.isFinishing());
    }
}
like image 55
Konstantin Loginov Avatar answered Sep 21 '22 08:09

Konstantin Loginov


You can try:

Robolectric.pauseMainLooper();
Robolectric.getUiThreadScheduler().advanceBy(intervalMs);
Robolectric.unPauseMainLooper();

or, if you just was the runnable to be called:

Robolectric.runUiThreadTasksIncludingDelayedTasks();
like image 34
IuriiO Avatar answered Sep 21 '22 08:09

IuriiO