Android - How to wait for async operations (maybe Observables or EvenBus) with IdlingResource for JUnit assertions.
@RunWith(AndroidJUnit4.class)
@LargeTest
public class LoginActivityTests {
@Test
public void loginSucceed() {
EventBusIdlingResource eventBusIdlingResource = new EventBusIdlingResource();
registerIdlingResources(eventBusIdlingResource);
click(R.id.button_login);
IdlingResourceSleeper.sleep(eventBusIdlingResource);
Customer customer = Customer.getCurrentObservable().toBlocking().first();
assertThat(customer.getSession()).isNotNull()
unregisterIdlingResources(eventBusIdlingResource);
}
}
import android.support.test.espresso.IdlingResource;
/**
* Have functions to sleep the processor because assertions are not linked to
* {@link IdlingResource} to do assertions, so should be used before asserts if there's an
* idle process.
*/
public class IdlingResourceSleeper {
private static final int SLEEPS_LIMIT = 50;
private static final int SLEEPS_TIME = 10;
/**
* Used to sleep {@link IdlingResourceSleeper#SLEEPS_LIMIT} times and
* {@link IdlingResourceSleeper#SLEEPS_TIME} ms until idlingResource.isIdleNow() is false.
*
* @param idlingResource
*/
public static void sleep(IdlingResource idlingResource) {
int sleeps = 0;
while (!idlingResource.isIdleNow() || sleeps < SLEEPS_LIMIT) {
android.os.SystemClock.sleep(SLEEPS_TIME);
sleeps++;
}
}
}
public class EventBusIdlingResource implements IdlingResource {
private boolean busUpdated;
public EventBusIdlingResource() {
busUpdated = false;
Bus.getInstance().register(this);
}
@Override
public boolean isIdleNow() {
if (busUpdated) {
Bus.getInstance().unregister(this);
}
return busUpdated;
}
public void onEvent(OrderUpdatedEvent event) {
busUpdated = true;
}
public void onEvent(SecondLapseEvent event) {
busUpdated = true;
}
public void onEvent(ValidationCodeEvent event) {
busUpdated = true;
}
}