2

I want to test method that are executed in AsyncTask. I already mocked all methods inside. What I have -

  1. Static method that get all required parameters and do new AsyncTask().executeOnExecutor();
  2. In onPostExecute() I call callback with result.

For test I'm using:

    testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.2.2"
testCompile "org.powermock:powermock-module-junit4:1.6.4"
testCompile "org.powermock:powermock-module-junit4-rule:1.6.4"
testCompile "org.powermock:powermock-api-mockito:1.6.4"
testCompile "org.powermock:powermock-classloading-xstream:1.6.4"

But callback is never called. Example :

  @RunWith(RobolectricTestRunner.class)
    @Config(constants = BuildConfig.class, sdk = 24,
            application = StubApplicationClass.class)
    @PowerMockIgnore({"org.mockito.", "android.*"})
    @PrepareForTest(BaseHttpClient.class)

    @SuppressStaticInitializationFor("io.realm.internal.Util")
    public class GetDataTest {

        @Rule
        public PowerMockRule rule = new PowerMockRule();
        ....................................

        @Test
        public void getDataTest() throws Exception {
        System.out.println("started");
        BaseAsyncClient.doAsync(UserPublicDataTable, Actions,
                list, new IHttpResponse<String>() {
                    @Override
                    public void httpResponse(@Nullable String response) {
                        assertNotNull(response); System.out.println("onPostExecute()");
                    }
                });
        System.out.println("finished");
    }

onPostExecute - is never printed.

When I call:

Robolectric.flushBackgroundThreadScheduler();

I receive an exception:

java.lang.NullPointerException
    at org.robolectric.Robolectric.getBackgroundThreadScheduler(Robolectric.java:193)
    at org.robolectric.Robolectric.flushBackgroundThreadScheduler(Robolectric.java:200)

How can I test AsyncTask with robolectric, powermock ?

Update:

As I see ShadowApplication.getInstance() == null, that is why I receive NPE exception when calls 'flushBackgroundThreadScheduler'.

I created custom runner to create custom application, but it is still null.

To fix NPE in Application migrated to:

testCompile "org.robolectric:robolectric:3.0"

UPDATE:

When I create AsyncTask in @Test - it works

new AsyncTask() {
        @Override
        protected Object doInBackground(Object[] params) {
            System.out.println("empty async task");
            return null;
        }
    }.execute();
    ShadowApplication.runBackgroundTasks();
    Robolectric.flushBackgroundThreadScheduler();

So problem when task is created with 'static' method

Community
  • 1
  • 1
ilbets
  • 710
  • 1
  • 9
  • 35

1 Answers1

1

I managed to fix this problem with a little work-around:

  1. downgrade version to testCompile "org.robolectric:robolectric:3.0"
  2. Call async tas new AsyncTask.execute()
  3. Call ShadowApplication.executeBackgroundTasks();
  4. Sleep while background executed Thread.sleep(1000);
  5. Execute foregroud tasks with ShadowScheduler

Unfortunately, this require to wait till background thread executed. I didn't found a way to replace background thread with main as well.

In the end, I migrated from AsyncTask to RxJava. There, with default methods I replace thread pool executor with the same thread execution:

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
 RxJavaPlugins.setIoSchedulerHandler(new Function<Scheduler, Scheduler>() {
            @Override
            public Scheduler apply(Scheduler scheduler) throws Exception {
                return ImmediateThinScheduler.INSTANCE;
            }
        });

Schedulers.io() is the thread pool executor, I replace it with the same thread executor ImmediateThinScheduler.INSTANCE

ilbets
  • 710
  • 1
  • 9
  • 35