Skip to content

Instantly share code, notes, and snippets.

@caseycrites
Created July 10, 2012 15:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caseycrites/3084274 to your computer and use it in GitHub Desktop.
Save caseycrites/3084274 to your computer and use it in GitHub Desktop.
Properly test async Android code
/*
I've been writing tests for Android code that uses Handlers to communicate with background threads.
I couldn't get my callbacks to be called back to.
I got angry.
I finally found the solution...after way too much looking.
Here it is.
*/
package com.caseycrites.android.testexample
import java.util.concurrent.CountDownLatch;
import junit.framework.Assert;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.test.InstrumentationTestCase;
import com.caseycrites.android.SomeClass;
/*
Make sure you extend InstrumentationTestCase.
Maybe that's not true, you can mess around with it, let me know if others work.
*/
public class AsyncTest extends InstrumentationTestCase {
int what = -1;
Object obj;
CountDownLatch latch;
SomeClass someClass;
@Override
public void setUp() throws Exception {
super.setUp();
this.someClass = new SomeClass();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
this.what = -1;
this.obj = null;
}
public void testHandlerCode() {
this.latch = new CountDownLatch(1);
new LooperThread() {
@Override
public void run() {
AsyncTest.this.someClass.someMethod(new Handler() {
@Override
public void handleMessage(Message message) {
AsyncTest.this.what = message.what;
AsyncTest.this.obj = message.obj;
AsyncTest.this.latch.countDown();
}
});
}
}.start();
this.latch.await();
Assert.assertNotEquals(-1, this.what);
Assert.assertNotNull(this.obj);
}
static class LooperThread extends Thread {
@Override
public void start() {
new Thread() {
@Override
public void run() {
Looper.prepare();
LooperThread.this.run();
Looper.run();
}
}.start();
}
}
}
/*
Note: This should also work fine for testing AsyncTasks.
What I don't get and maybe someone can explain it to me, is why can't I send messages to my handler without creating a new Thread with a Looper?
InstrumentationTestCase (and most other Android supplied TestCases...I think?) have their own Looper? So why can't I send it messages?
Perhaps the Looper's message queue is reserved for the Android TestRunner's use only?
*/
@jonathankau
Copy link

This is life changing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment