3
votes

I am trying to create Unit test on Android project which is working with URL requests. I use loopj library but something doesn't work. Internet is enabled in my manifest:

<uses-permission android:name="android.permission.INTERNET" />

Java code in a test method:

    AsyncHttpClient client = new AsyncHttpClient();
    client.get("http://www.yahoo.com", new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(String response) {
            System.out.println(response); // <------ I never get here!?!?!
        }
    });

Folowing procedure (without loopj) works in same unit test method:

    URL yahoo;
    yahoo = new URL("http://www.yahoo.com/");
    BufferedReader in;
    in = new BufferedReader(new InputStreamReader(yahoo.openStream()));
        String inputLine;
    while ((inputLine = in.readLine()) != null) {
             System.out.println(inputLine);

            }
    in.close();

It seems like loopj requests dont work in unit test class but it works normal in basic Activity class. Any suggestion?

3

3 Answers

5
votes

The problem is since loopj uses android.os.AsyncTask which doesnt work in unit test environment.

Key to success is "runTestOnUiThread" method.

public void testAsyncHttpClient() throws Throwable {
  final CountDownLatch signal = new CountDownLatch(1);
  final AsyncHttpClient httpClient = new AsyncHttpClient();
  final StringBuilder strBuilder = new StringBuilder();

  runTestOnUiThread(new Runnable() { // THIS IS THE KEY TO SUCCESS
    @Override
    public void run() {
      httpClient
          .get(
              "https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true",
              new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(String response) {
                  // Do not do assertions here or it will stop the whole testing upon failure
                  strBuilder.append(response);
                }

                public void onFinish() {
                  signal.countDown();
                }
              });
    }
  });

  try {
    signal.await(30, TimeUnit.SECONDS); // wait for callback
  } catch (InterruptedException e) {
    e.printStackTrace();
  }

  JSONObject jsonRes = new JSONObject(strBuilder.toString());
  try {
    // Test your jsonResult here
    assertEquals(6253282, jsonRes.getInt("id"));
  } catch (Exception e) {

  }

  assertEquals(0, signal.getCount());
}

Ful thread: https://github.com/loopj/android-async-http/issues/173

1
votes

Careful that you haven't forgotten to declare network access in the manifest i.e.

<manifest ....>
...
    <uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
0
votes

An asynchronous callback-based Http client for Android built on top of Apache’s HttpClient libraries. All requests are made outside of your app’s main UI thread, but any callback logic will be executed on the same thread as the callback was created using Android’s Handler message passing.

Check http://loopj.com/android-async-http/ this may help you !