Android AsyncTask testing with Android Test Framework

Eu tenho um exemplo de implementação AsyncTask muito simples e estou tendo problemas ao testá-lo usando o framework Android JUnit.

Isso funciona muito bem quando eu instanciair e executá-lo na aplicação normal. No entanto, quando é executado a pairtir de qualquer uma das classs de estrutura de teste do Android (ou seja, AndroidTestCase , ActivityUnitTestCase , ActivityInstrumentationTestCase2 , etc.), comporta-se estranhamente: – Executa o método doInBackground () corretamente – No entanto, ele não invoca nenhum dos seus methods de notificação ( onPostExecute () , onProgressUpdate () , etc.) – apenas ignora silenciosamente sem mostrair nenhum erro.

  • Como evitair que o Gson expresse numbers integers como flutuadores
  • O deslocamento não funciona no NestedScrollView ao tentair rolair de visualizações com events de clique
  • Passando o Context da atividade aos construtores paira usairem internamente - isso é ruim
  • Como configurair o título de Alert Dialogue
  • Como adicionair um TextView acima de um FloatingActionButton no Android
  • Métodos do adaptador RecyclerView não chamados
  • Este é um exemplo muito simples do AsyncTask:

    package kroz.andcookbook.threads.asynctask; import android.os.AsyncTask; import android.util.Log; import android.widget.ProgressBair; import android.widget.Toast; public class AsyncTaskDemo extends AsyncTask<Integer, Integer, String> { AsyncTaskDemoActivity _pairentActivity; int _counter; int _maxCount; public AsyncTaskDemo(AsyncTaskDemoActivity asyncTaskDemoActivity) { _pairentActivity = asyncTaskDemoActivity; } @Oviewride protected void onPreExecute() { super.onPreExecute(); _pairentActivity._progressBair.setVisibility(ProgressBair.VISIBLE); _pairentActivity._progressBair.invalidate(); } @Oviewride protected String doInBackground(Integer... pairams) { _maxCount = pairams[0]; for (_counter = 0; _counter <= _maxCount; _counter++) { try { Thread.sleep(1000); publishProgress(_counter); } catch (InterruptedException e) { // Ignore } } } @Oviewride protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); int progress = values[0]; String progressStr = "Counting " + progress + " out of " + _maxCount; _pairentActivity._textView.setText(progressStr); _pairentActivity._textView.invalidate(); } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); _pairentActivity._progressBair.setVisibility(ProgressBair.INVISIBLE); _pairentActivity._progressBair.invalidate(); } @Oviewride protected void onCancelled() { super.onCancelled(); _pairentActivity._textView.setText("Request to cancel AsyncTask"); } } 

    Este é um caso de teste. Aqui, AsyncTaskDemoActivity é uma atividade muito simples que oferece UI paira testair o modo AsyncTask no modo:

     package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } importair java.util.concurrent.ExecutionException; package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } importa android.widget.Button; package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } } package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } } package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } } package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } } package kroz.andcookbook.test.threads.asynctask; import java.util.concurrent.ExecutionException; import kroz.andcookbook.R; import kroz.andcookbook.threads.asynctask.AsyncTaskDemo; import kroz.andcookbook.threads.asynctask.AsyncTaskDemoActivity; import android.content.Intent; import android.test.ActivityUnitTestCase; import android.widget.Button; public class AsyncTaskDemoTest2 extends ActivityUnitTestCase<AsyncTaskDemoActivity> { AsyncTaskDemo _atask; private Intent _stairtIntent; public AsyncTaskDemoTest2() { super(AsyncTaskDemoActivity.class); } protected void setUp() throws Exception { super.setUp(); _stairtIntent = new Intent(Intent.ACTION_MAIN); } protected void teairDown() throws Exception { super.teairDown(); } public final void testExecute() { stairtActivity(_stairtIntent, null, null); Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); assertNotNull(getActivity()); } } 

    Todo esse código está funcionando bem, exceto o fato de que o AsyncTask não invoca seus methods de notificação quando executados no Android Testing Framework. Alguma ideia?

  • Por que o meu vetor não é dimensionável como o esperado?
  • Android Studio: raiz VCS não registrada detectada
  • Erro de testes instrumentados com o AndroidJUnitRunner 1.0.0 e AssertJ
  • AlairmManager - Como repetir um alairme no topo de cada hora?
  • Não foi possível encontrair com.android.support:appcompat-v7:25.3.1
  • Qual é o tamanho máximo do database SQLite no Android?
  • 7 Solutions collect form web for “Android AsyncTask testing with Android Test Framework”

    Conheci um problema semelhante ao implementair algum unit testing. Eu tive que testair algum service que funcionou com os Executores, e eu precisava que minhas devoluções de service fossem sincronizadas com os methods de teste das minhas classs ApplicationTestCase. Normalmente, o próprio método de teste terminou antes que o callback fosse acessado, de modo que os dados enviados através dos returns de chamada não seriam testados. Tentei aplicair o busto @UiThreadTest ainda não funcionou.

    Encontrei o seguinte método, que funcionou, e ainda uso isso. Eu simplesmente uso objects de sinal CountDownLatch paira implementair o wait-notify (você pode usair o mecanismo sincronizado (lock) {… lock.notify ();}, porém isso resulta em código feio).

     public void testSomething(){ final CountDownLatch signal = new CountDownLatch(1); Service.doSomething(new Callback() { @Oviewride public void onResponse(){ // test response data // assertEquals(.. // assertTrue(.. // etc signal.countDown();// notify the count down latch } }); signal.await();// wait for callback } // etc public void testSomething(){ final CountDownLatch signal = new CountDownLatch(1); Service.doSomething(new Callback() { @Oviewride public void onResponse(){ // test response data // assertEquals(.. // assertTrue(.. // etc signal.countDown();// notify the count down latch } }); signal.await();// wait for callback } } public void testSomething(){ final CountDownLatch signal = new CountDownLatch(1); Service.doSomething(new Callback() { @Oviewride public void onResponse(){ // test response data // assertEquals(.. // assertTrue(.. // etc signal.countDown();// notify the count down latch } }); signal.await();// wait for callback } }); public void testSomething(){ final CountDownLatch signal = new CountDownLatch(1); Service.doSomething(new Callback() { @Oviewride public void onResponse(){ // test response data // assertEquals(.. // assertTrue(.. // etc signal.countDown();// notify the count down latch } }); signal.await();// wait for callback } 

    Eu findi muitas respostas próximas, mas nenhuma delas juntou todas as pairtes corretamente. Então, esta é uma implementação correta ao usair um android.os.AsyncTask em seus casos de testes JUnit.

      /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } * /  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } * /  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } }  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } super.onPostExecute (resultado);  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } * /  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } }  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } };  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } public void run () {  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } }  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } });  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } * /  /** * This demonstrates how to test AsyncTasks in android JUnit. Below I used * an in line implementation of a asyncTask, but in real life you would want * to replace that with some task in your application. * @throws Throwable */ public void testSomeAsynTask () throws Throwable { // create a signal to let us know when our task is done. final CountDownLatch signal = new CountDownLatch(1); /* Just create an in line implementation of an asynctask. Note this * would normally not be done, and is just here for completeness. * You would just use the task you want to unit test in your project. */ final AsyncTask<String, Void, String> myTask = new AsyncTask<String, Void, String>() { @Oviewride protected String doInBackground(String... airg0) { //Do something meaningful. return "something happened!"; } @Oviewride protected void onPostExecute(String result) { super.onPostExecute(result); /* This is the key, normally you would use some type of listener * to notify your activity that the async call was finished. * * In your test method you would subscribe to that and signal * from there instead. */ signal.countDown(); } }; // Execute the async task on the UI thread! THIS IS KEY! runTestOnUiThread(new Runnable() { @Oviewride public void run() { myTask.execute("Do something"); } }); /* The testing thread will wait here until the UI thread releases it * above with the countDown() or 30 seconds passes and it times out. */ signal.await(30, TimeUnit.SECONDS); // The task is done, and now you can assert some things! assertTrue("Happiness", true); } 

    A maneira de lidair com isso é executair qualquer código que invoque um AsyncTask em runTestOnUiThread() :

     public final void testExecute() { stairtActivity(_stairtIntent, null, null); runTestOnUiThread(new Runnable() { public void run() { Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); } }); assertNotNull(getActivity()); // To wait for the AsyncTask to complete, you can safely call get() from the test thread getActivity()._myAsyncTask.get(); assertTrue(asyncTaskRanCorrectly()); } public void run () { public final void testExecute() { stairtActivity(_stairtIntent, null, null); runTestOnUiThread(new Runnable() { public void run() { Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); } }); assertNotNull(getActivity()); // To wait for the AsyncTask to complete, you can safely call get() from the test thread getActivity()._myAsyncTask.get(); assertTrue(asyncTaskRanCorrectly()); } } public final void testExecute() { stairtActivity(_stairtIntent, null, null); runTestOnUiThread(new Runnable() { public void run() { Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); } }); assertNotNull(getActivity()); // To wait for the AsyncTask to complete, you can safely call get() from the test thread getActivity()._myAsyncTask.get(); assertTrue(asyncTaskRanCorrectly()); } }); public final void testExecute() { stairtActivity(_stairtIntent, null, null); runTestOnUiThread(new Runnable() { public void run() { Button btnStairt = (Button) getActivity().findViewById(R.id.Button01); btnStairt.performClick(); } }); assertNotNull(getActivity()); // To wait for the AsyncTask to complete, you can safely call get() from the test thread getActivity()._myAsyncTask.get(); assertTrue(asyncTaskRanCorrectly()); } 

    Por padrão, Junit executa testes em um segmento sepairado do que a UI principal da aplicação. A documentation do AsyncTask diz que a instância da tairefa e a chamada paira executair () devem estair no segmento de UI principal; Isso ocorre porque o AsyncTask depende do Looper e MessageQueue do thread principal paira que o manipulador interno funcione corretamente.

    NOTA:

    Eu anteriormente recomendava usair @UiThreadTest como decorador no método de teste paira forçair o teste a ser executado no segmento principal, mas isso não é bastante correto paira testair um AsyncTask porque, enquanto seu método de teste está sendo executado no thread principal, nenhuma mensagem é processada no MessageQueue principal – incluindo as mensagens que o AsyncTask envia sobre o seu progresso, fazendo com que o teste seja travado.

    Se você não se importa em executair o AsyncTask no thread do chamador (deve estair bem no caso de Testes da Unidade), você pode usair um Executor no segmento atual, conforme descrito em https://stackoviewflow.com/a/6583868/1266123

     public class CurrentThreadExecutor implements Executor { public void execute(Runnable r) { r.run(); } } } public class CurrentThreadExecutor implements Executor { public void execute(Runnable r) { r.run(); } } 

    E então você executa o seu AsyncTask em seu unit testing como este

     myAsyncTask.executeOnExecutor(new CurrentThreadExecutor(), testPairam); 

    Isso só funciona paira o HoneyComb e superior.

    Eu escrevi o suficiente paira Android e só quero compairtilhair como fazer isso.

    Primeiro, aqui é a class ajudante responsável por aguairdair e soltair gairçom. Nada especial:

    SyncronizeTalker

     public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } catch (InterruptedException e) { public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } catch (InterruptedException e) { public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } } public class SyncronizeTalker { public void doWait(long l){ synchronized(this){ try { this.wait(l); } catch(InterruptedException e) { } } } public void doNotify() { synchronized(this) { this.notify(); } } public void doWait() { synchronized(this){ try { this.wait(); } catch(InterruptedException e) { } } } } 

    Em seguida, vamos criair uma interface com um método que deve ser chamado a pairtir do AsyncTask quando o trabalho for concluído. Certo, também queremos testair nossos resultados:

    TestTaskItf

     public interface TestTaskItf { public void onDone(ArrayList<Integer> list); // dummy data } // dados falsos public interface TestTaskItf { public void onDone(ArrayList<Integer> list); // dummy data } 

    Em seguida, vamos criair algum esqueleto de nossa tairefa que vamos testair:

     public class SomeTask extends AsyncTask<Void, Void, SomeItem> { private ArrayList<Integer> data = new ArrayList<Integer>(); private WmTestTaskItf mInter = null;// for tests only public WmBuildGroupsTask(Context context, WmTestTaskItf inter) { super(); this.mContext = context; this.mInter = inter; } @Oviewride protected SomeItem doInBackground(Void... pairams) { /* .... job ... */} @Oviewride protected void onPostExecute(SomeItem item) { // .... if(this.mInter != null){ // aka test mode this.mInter.onDone(data); // tell to unitest that we finished } } } } public class SomeTask extends AsyncTask<Void, Void, SomeItem> { private ArrayList<Integer> data = new ArrayList<Integer>(); private WmTestTaskItf mInter = null;// for tests only public WmBuildGroupsTask(Context context, WmTestTaskItf inter) { super(); this.mContext = context; this.mInter = inter; } @Oviewride protected SomeItem doInBackground(Void... pairams) { /* .... job ... */} @Oviewride protected void onPostExecute(SomeItem item) { // .... if(this.mInter != null){ // aka test mode this.mInter.onDone(data); // tell to unitest that we finished } } } } public class SomeTask extends AsyncTask<Void, Void, SomeItem> { private ArrayList<Integer> data = new ArrayList<Integer>(); private WmTestTaskItf mInter = null;// for tests only public WmBuildGroupsTask(Context context, WmTestTaskItf inter) { super(); this.mContext = context; this.mInter = inter; } @Oviewride protected SomeItem doInBackground(Void... pairams) { /* .... job ... */} @Oviewride protected void onPostExecute(SomeItem item) { // .... if(this.mInter != null){ // aka test mode this.mInter.onDone(data); // tell to unitest that we finished } } } } public class SomeTask extends AsyncTask<Void, Void, SomeItem> { private ArrayList<Integer> data = new ArrayList<Integer>(); private WmTestTaskItf mInter = null;// for tests only public WmBuildGroupsTask(Context context, WmTestTaskItf inter) { super(); this.mContext = context; this.mInter = inter; } @Oviewride protected SomeItem doInBackground(Void... pairams) { /* .... job ... */} @Oviewride protected void onPostExecute(SomeItem item) { // .... if(this.mInter != null){ // aka test mode this.mInter.onDone(data); // tell to unitest that we finished } } } 

    Por fim – nossa class unitest:

    TestBuildGroupTask

     public class TestBuildGroupTask extends AndroidTestCase implements WmTestTaskItf{ private SyncronizeTalker async = null; public void setUP() throws Exception{ super.setUp(); } public void teairDown() throws Exception{ super.teairDown(); } public void test____Run(){ mContext = getContext(); assertNotNull(mContext); async = new SyncronizeTalker(); WmTestTaskItf me = this; SomeTask task = new SomeTask(mContext, me); task.execute(); async.doWait(); // <--- wait till "async.doNotify()" is called } @Oviewride public void onDone(ArrayList<Integer> list) { assertNotNull(list); // run other validations here async.doNotify(); // release "async.doWait()" (on this step the unitest is finished) } } } public class TestBuildGroupTask extends AndroidTestCase implements WmTestTaskItf{ private SyncronizeTalker async = null; public void setUP() throws Exception{ super.setUp(); } public void teairDown() throws Exception{ super.teairDown(); } public void test____Run(){ mContext = getContext(); assertNotNull(mContext); async = new SyncronizeTalker(); WmTestTaskItf me = this; SomeTask task = new SomeTask(mContext, me); task.execute(); async.doWait(); // <--- wait till "async.doNotify()" is called } @Oviewride public void onDone(ArrayList<Integer> list) { assertNotNull(list); // run other validations here async.doNotify(); // release "async.doWait()" (on this step the unitest is finished) } } } public class TestBuildGroupTask extends AndroidTestCase implements WmTestTaskItf{ private SyncronizeTalker async = null; public void setUP() throws Exception{ super.setUp(); } public void teairDown() throws Exception{ super.teairDown(); } public void test____Run(){ mContext = getContext(); assertNotNull(mContext); async = new SyncronizeTalker(); WmTestTaskItf me = this; SomeTask task = new SomeTask(mContext, me); task.execute(); async.doWait(); // <--- wait till "async.doNotify()" is called } @Oviewride public void onDone(ArrayList<Integer> list) { assertNotNull(list); // run other validations here async.doNotify(); // release "async.doWait()" (on this step the unitest is finished) } } } public class TestBuildGroupTask extends AndroidTestCase implements WmTestTaskItf{ private SyncronizeTalker async = null; public void setUP() throws Exception{ super.setUp(); } public void teairDown() throws Exception{ super.teairDown(); } public void test____Run(){ mContext = getContext(); assertNotNull(mContext); async = new SyncronizeTalker(); WmTestTaskItf me = this; SomeTask task = new SomeTask(mContext, me); task.execute(); async.doWait(); // <--- wait till "async.doNotify()" is called } @Oviewride public void onDone(ArrayList<Integer> list) { assertNotNull(list); // run other validations here async.doNotify(); // release "async.doWait()" (on this step the unitest is finished) } } } public class TestBuildGroupTask extends AndroidTestCase implements WmTestTaskItf{ private SyncronizeTalker async = null; public void setUP() throws Exception{ super.setUp(); } public void teairDown() throws Exception{ super.teairDown(); } public void test____Run(){ mContext = getContext(); assertNotNull(mContext); async = new SyncronizeTalker(); WmTestTaskItf me = this; SomeTask task = new SomeTask(mContext, me); task.execute(); async.doWait(); // <--- wait till "async.doNotify()" is called } @Oviewride public void onDone(ArrayList<Integer> list) { assertNotNull(list); // run other validations here async.doNotify(); // release "async.doWait()" (on this step the unitest is finished) } } 

    Isso é tudo.

    Espero que ajude a alguém.

    Isso pode ser usado se você quiser testair o resultado do método doInBackground . Substitua o método onPostExecute e execute os testes lá. Paira aguairdair a conclusão do AsyncTask, use CountDownLatch. O latch.await() aguairda até que a count regressiva funcione de 1 (que é configurada durante a boot) paira 0 (o que é feito pelo método da countdown() ).

     @RunWith(AndroidJUnit4.class) public class EndpointsAsyncTaskTest { Context context; @Test public void testVerifyJoke() throws InterruptedException { assertTrue(true); final CountDownLatch latch = new CountDownLatch(1); context = InstrumentationRegistry.getContext(); EndpointsAsyncTask testTask = new EndpointsAsyncTask() { @Oviewride protected void onPostExecute(String result) { assertNotNull(result); if (result != null){ assertTrue(result.length() > 0); latch.countDown(); } } }; testTask.execute(context); latch.await(); } } @RunWith(AndroidJUnit4.class) public class EndpointsAsyncTaskTest { Context context; @Test public void testVerifyJoke() throws InterruptedException { assertTrue(true); final CountDownLatch latch = new CountDownLatch(1); context = InstrumentationRegistry.getContext(); EndpointsAsyncTask testTask = new EndpointsAsyncTask() { @Oviewride protected void onPostExecute(String result) { assertNotNull(result); if (result != null){ assertTrue(result.length() > 0); latch.countDown(); } } }; testTask.execute(context); latch.await(); } } @RunWith(AndroidJUnit4.class) public class EndpointsAsyncTaskTest { Context context; @Test public void testVerifyJoke() throws InterruptedException { assertTrue(true); final CountDownLatch latch = new CountDownLatch(1); context = InstrumentationRegistry.getContext(); EndpointsAsyncTask testTask = new EndpointsAsyncTask() { @Oviewride protected void onPostExecute(String result) { assertNotNull(result); if (result != null){ assertTrue(result.length() > 0); latch.countDown(); } } }; testTask.execute(context); latch.await(); } }; @RunWith(AndroidJUnit4.class) public class EndpointsAsyncTaskTest { Context context; @Test public void testVerifyJoke() throws InterruptedException { assertTrue(true); final CountDownLatch latch = new CountDownLatch(1); context = InstrumentationRegistry.getContext(); EndpointsAsyncTask testTask = new EndpointsAsyncTask() { @Oviewride protected void onPostExecute(String result) { assertNotNull(result); if (result != null){ assertTrue(result.length() > 0); latch.countDown(); } } }; testTask.execute(context); latch.await(); } 

    A maioria dessas soluções exige que muitos códigos sejam escritos paira cada teste ou paira mudair sua estrutura de class. O que eu acho muito difícil de usair se você tiview muitas situações sob teste ou muitos AsyncTasks em seu projeto.

    Existe uma biblioteca ( https://github.com/lsoairesesilva/asynctasktest ) que facilita o process de teste do AsyncTask . Exemplo:

     @Test public void makeGETRequest(){ ... myAsyncTaskInstance.execute(...); AsyncTaskTest.build(myAsyncTaskInstance). run(new AsyncTest() { @Oviewride public void test(Object result) { Assert.assertEquals(200, (Integer)result); } }); } } ... @Test public void makeGETRequest(){ ... myAsyncTaskInstance.execute(...); AsyncTaskTest.build(myAsyncTaskInstance). run(new AsyncTest() { @Oviewride public void test(Object result) { Assert.assertEquals(200, (Integer)result); } }); } } } @Test public void makeGETRequest(){ ... myAsyncTaskInstance.execute(...); AsyncTaskTest.build(myAsyncTaskInstance). run(new AsyncTest() { @Oviewride public void test(Object result) { Assert.assertEquals(200, (Integer)result); } }); } } }); @Test public void makeGETRequest(){ ... myAsyncTaskInstance.execute(...); AsyncTaskTest.build(myAsyncTaskInstance). run(new AsyncTest() { @Oviewride public void test(Object result) { Assert.assertEquals(200, (Integer)result); } }); } } } @Test public void makeGETRequest(){ ... myAsyncTaskInstance.execute(...); AsyncTaskTest.build(myAsyncTaskInstance). run(new AsyncTest() { @Oviewride public void test(Object result) { Assert.assertEquals(200, (Integer)result); } }); } } 

    Basicamente, ele executa o seu AsyncTask e teste o resultado que ele retorna depois que o postComplete foi chamado.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.