blob: 61f2954459fef690021cdffde14dfae0c1b7bbb3 [file] [log] [blame]
package org.robolectric.shadows;
import android.os.AsyncTask;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.TestRunners;
import org.robolectric.util.Join;
import org.robolectric.util.Transcript;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@RunWith(TestRunners.WithDefaults.class)
public class AsyncTaskTest {
private Transcript transcript;
@Before
public void setUp() throws Exception {
transcript = new Transcript();
ShadowApplication.getInstance().getBackgroundScheduler().pause();
ShadowLooper.getUiThreadScheduler().pause();
}
@Test
public void testNormalFlow() throws Exception {
AsyncTask<String, String, String> asyncTask = new MyAsyncTask();
asyncTask.execute("a", "b");
transcript.assertEventsSoFar("onPreExecute");
Robolectric.runBackgroundTasks();
transcript.assertEventsSoFar("doInBackground a, b");
assertEquals("Result should get stored in the AsyncTask", "c", asyncTask.get(100, TimeUnit.MILLISECONDS));
ShadowLooper.runUiThreadTasks();
transcript.assertEventsSoFar("onPostExecute c");
}
@Test
public void testCancelBeforeBackground() throws Exception {
AsyncTask<String, String, String> asyncTask = new MyAsyncTask();
asyncTask.execute("a", "b");
transcript.assertEventsSoFar("onPreExecute");
assertTrue(asyncTask.cancel(true));
assertTrue(asyncTask.isCancelled());
Robolectric.runBackgroundTasks();
transcript.assertNoEventsSoFar();
ShadowLooper.runUiThreadTasks();
transcript.assertEventsSoFar("onCancelled");
}
@Test
public void testCancelBeforePostExecute() throws Exception {
AsyncTask<String, String, String> asyncTask = new MyAsyncTask();
asyncTask.execute("a", "b");
transcript.assertEventsSoFar("onPreExecute");
Robolectric.runBackgroundTasks();
transcript.assertEventsSoFar("doInBackground a, b");
assertEquals("Result should get stored in the AsyncTask", "c", asyncTask.get(100, TimeUnit.MILLISECONDS));
assertFalse(asyncTask.cancel(true));
assertFalse(asyncTask.isCancelled());
ShadowLooper.runUiThreadTasks();
transcript.assertEventsSoFar("onPostExecute c");
}
@Test
public void progressUpdatesAreQueuedUntilBackgroundThreadFinishes() throws Exception {
AsyncTask<String, String, String> asyncTask = new MyAsyncTask() {
@Override
protected String doInBackground(String... strings) {
publishProgress("33%");
publishProgress("66%");
publishProgress("99%");
return "done";
}
};
asyncTask.execute("a", "b");
transcript.assertEventsSoFar("onPreExecute");
Robolectric.runBackgroundTasks();
transcript.assertNoEventsSoFar();
assertEquals("Result should get stored in the AsyncTask", "done", asyncTask.get(100, TimeUnit.MILLISECONDS));
ShadowLooper.runUiThreadTasks();
transcript.assertEventsSoFar(
"onProgressUpdate 33%",
"onProgressUpdate 66%",
"onProgressUpdate 99%",
"onPostExecute done");
}
@Test
public void executeReturnsAsyncTask() throws Exception {
ShadowApplication.getInstance().getBackgroundScheduler().unPause();
AsyncTask<String, String, String> asyncTask = new MyAsyncTask();
assertThat(asyncTask.execute("a", "b").get()).isEqualTo("c");
}
@Test
public void shouldGetStatusForAsyncTask() throws Exception {
AsyncTask<String, String, String> asyncTask = new MyAsyncTask();
assertThat(asyncTask.getStatus()).isEqualTo(AsyncTask.Status.PENDING);
asyncTask.execute("a");
assertThat(asyncTask.getStatus()).isEqualTo(AsyncTask.Status.RUNNING);
ShadowApplication.getInstance().getBackgroundScheduler().unPause();
assertThat(asyncTask.getStatus()).isEqualTo(AsyncTask.Status.FINISHED);
}
@Test
public void onPostExecute_doesNotSwallowExceptions() throws Exception {
ShadowApplication.getInstance().getBackgroundScheduler().unPause();
ShadowLooper.getUiThreadScheduler().unPause();
AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
throw new RuntimeException("Don't swallow me!");
}
};
try {
asyncTask.execute();
fail("Task swallowed onPostExecute() exception!");
} catch (RuntimeException e) {
assertThat(e.getCause().getMessage()).isEqualTo("java.lang.RuntimeException: Don't swallow me!");
}
}
@Test
public void executeOnExecutor_usesPassedExecutor() throws Exception {
AsyncTask<String, String, String> asyncTask = new MyAsyncTask();
assertThat(asyncTask.getStatus()).isEqualTo(AsyncTask.Status.PENDING);
asyncTask.executeOnExecutor(new ImmediateExecutor(), "a", "b");
assertThat(asyncTask.getStatus()).isEqualTo(AsyncTask.Status.FINISHED);
transcript.assertEventsSoFar("onPreExecute", "doInBackground a, b");
assertEquals("Result should get stored in the AsyncTask", "c", asyncTask.get());
ShadowLooper.runUiThreadTasks();
transcript.assertEventsSoFar("onPostExecute c");
}
private class MyAsyncTask extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
transcript.add("onPreExecute");
}
@Override
protected String doInBackground(String... strings) {
transcript.add("doInBackground " + Join.join(", ", (Object[]) strings));
return "c";
}
@Override
protected void onProgressUpdate(String... values) {
transcript.add("onProgressUpdate " + Join.join(", ", (Object[]) values));
}
@Override
protected void onPostExecute(String s) {
transcript.add("onPostExecute " + s);
}
@Override
protected void onCancelled() {
transcript.add("onCancelled");
}
}
public class ImmediateExecutor implements Executor {
@Override
public void execute(Runnable command) {
command.run();
}
}
}