Reputation: 4530
using robolectric version 4.5.1
What is the difference between
shadowOf(getMainLooper()).idleFor(1, TimeUnit.MILLISECONDS);
and
shadowOf(getMainLooper()).idle();
shadowOf(getMainLooper()).idle(); is causing my test case to fail giving following exception message
Main looper has queued unexecuted runnables. This might be the cause of the test
failure. You might need a shadowOf(getMainLooper()).idle() call.
java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.
at org.robolectric.android.internal.AndroidTestEnvironment.checkStateAfterTestFailure(AndroidTestEnvironment.java:502)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:581)
at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:278)
at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
But shadowOf(getMainLooper()).idleFor(1, TimeUnit.MILLISECONDS); this works fine how?
as documentation idleFor Advances the system clock by the given time, then executes all posted tasks scheduled before or at the given time. What it means Advances the system clock? How my test is getting passed on using idleFor() instead of idle()
Upvotes: 0
Views: 2826
Reputation: 50
We can find both functions in ShadowPausedLooper:
@Override
public void idle() {
executeOnLooper(new IdlingRunnable());
}
@Override
public void idleFor(long time, TimeUnit timeUnit) {
long endingTimeMs = SystemClock.uptimeMillis() + timeUnit.toMillis(time);
long nextScheduledTimeMs = getNextScheduledTaskTime().toMillis();
while (nextScheduledTimeMs != 0 && nextScheduledTimeMs <= endingTimeMs) {
SystemClock.setCurrentTimeMillis(nextScheduledTimeMs);
idle();
nextScheduledTimeMs = getNextScheduledTaskTime().toMillis();
}
SystemClock.setCurrentTimeMillis(endingTimeMs);
// the last SystemClock update might have added new tasks to the main looper via Choreographer
// so idle once more.
idle();
}
idle()
will only run immediate Runnables
where idleFor()
will check for next scheduled task and if it exists move system time
SystemClock.setCurrentTimeMillis(nextScheduledTimeMs);
We can check ShadowPausedMessageQueue for getNextScheduledTaskTime()
Duration getNextScheduledTaskTime() {
Message next = peekNextExecutableMessage();
if (next == null) {
return Duration.ZERO;
}
return Duration.ofMillis(convertWhenToScheduledTime(shadowOfMsg(next).getWhen()));
}
Upvotes: 0