Unittesting AsyncTaskLoader with getLoaderResultSynchronously
Asked Answered
E

3

5

I am trying to create unit tests for a REST client that does some API calls. The client works fine in the live application, but I can't get it to run in the test case.

Apparantly, LoaderTestCase.getLoaderResultSynchronously() could be used here (at least according to Android reference, but it will not accept my loader. The code:

public void testGetEventInfo() {
    // Init some vars
    ...

    // Create & execute loader
    RESTLoader loader = new RESTLoader(getContext(),
            RESTLoader.HTTPVerb.GET, action, params, LOADER_GET_NEWS);
    getLoaderResultSynchronously(loader);
}

This yields the error getLoaderResultSynchronously(Loader) in the type LoaderTestCase is not applicable for the arguments (RESTLoader).

RESTLoader extends AsyncLoader. Note that I'm using the supportlibrary, maybe the Loader in there is incompatible? The documentation gives no information on this.

I've tried to solve this in several ways, though none seem to work:

  • Registered a listener to loader. However, the callback never triggers
  • Using CountdownLatch (also with a listener). Again, no trigger/countdown timeout.
  • Playing around with the type template (), without success.
  • Similar solutions on SO, though again failing to reach the listener.

Does anybody know why getLoaderResultSynchronously will not accept the loader? Or another clean way of testing the Loader, including a way to test return data? I can test handling the return data in a separate case, but I would also like to test the actual data.

Sincerely,

Etti answered 6/7, 2012 at 11:16 Comment(0)
S
6

Have you taken a look at the source code? You'll find the following import statements:

import android.content.Loader;
import android.content.Loader.OnLoadCompleteListener;

It doesn't look like Android offers a support version for LoaderTestCase. The easiest solution would be to temporarily change to the non-support LoaderManager (that is, have your class make use of the android.content.Loader instead), test your app, and then switch back to the support implementation. You might also consider copying the testing source code into your project, import the support LoaderManager, and execute it directly. I'm not familiar with the test libraries for Loaders but it doesn't seem outwardly obvious that this would cause any major issues.

Superabundant answered 9/7, 2012 at 22:10 Comment(1)
Thank you so much! I used the insights from your answer and instead of having my project use content.loader, I've copied the source from LoaderTestCase and had that use android.support.v4.loader. Clean testcase, clean code. Works like a charm.Etti
D
3

You can get sources from LoaderTestCase here, create SupportLoaderTestCase class from that sources in your test project and modify all namespaces to support library namespaces (e.g. change android.content.Loader with android.support.v4.content.Loader). Than you can extend your test case from SupportLoaderTestCase (not from LoaderTestCase) and use it without problems

Discomfort answered 16/1, 2014 at 15:41 Comment(0)
C
0

The method you are trying to call (getLoaderResultSynchronously) accepts an object of type android.content.Loader. If your RESTLoader class is not of that EXACT type then you will get this error. I suspect your class directly or indirectly extends android.support.v4.content.Loader, which would explain the error.

I am not aware of a back-port of LoaderTestCase that would support testing of this type of class.

Crookback answered 9/7, 2012 at 21:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.