Robolectric3でandroid.os.Handler
android.os.Handlerを使う場合のテストのメモ
例を上げると
package kinjouj.app.oretter;
import java.util.BitSet;
import android.os.Handler;
import android.os.Looper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
@RunWith(RobolectricGradleTestRunner.class)
public class SampleTest {
@Test
public void test() {
BitSet bs = new BitSet();
SampleHandler.run(bs);
assertThat(bs.get(0), is(true));
}
private static final class SampleHandler {
private static final Handler handler = new Handler(Looper.getMainLooper());
public static void run(final BitSet bitSet) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
bitSet.set(0);
}
}, 1000);
}
}
}
とやってもrunメソッドで作用するpostDelayedが作用するまで待ち処理しないと正常に作用しないはずなので
java.lang.AssertionError: Expected: is <true> but: was <false>
というようにテストが成功しない。こういう場合はShadowLooperなAPIを使えば良いとのこと
package kinjouj.app.oretter;
import java.util.BitSet;
import android.os.Handler;
import android.os.Looper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.shadows.ShadowLooper;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
@RunWith(RobolectricGradleTestRunner.class)
public class SampleTest {
@Test
public void test() {
BitSet bs = new BitSet();
SampleHandler.run(bs);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
assertThat(bs.get(0), is(true));
}
private static final class SampleHandler {
private static final Handler handler = new Handler(Looper.getMainLooper());
public static void run(final BitSet bitSet) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
bitSet.set(0);
}
}, 1000);
}
}
}
但し場合によってはnew Handlerをする引数にLooper.getMainLooper等を指定してないとRobolectricで正常に作用してくれない場合のケースも存在するっぽい