2015年9月15日火曜日

AndroidJUnitRunner で Toast や PopupWindow を表示するには

Toast、Dialog、PopupWindow など別の Window を使う操作をテストメソッド内で行うと、Handler が作れないと言われてエラーになります (PopupWindow を内包したユーティリティクラスのテストで困りました)。

例えば以下のテストを実行すると、Toast 部分で

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

になります。 @RunWith(AndroidJUnit4.class) @LargeTest public class SimpleMenuPopupTest { @Test public void showToastTest() { Context context = InstrumentationRegistry.getTargetContext(); Toast.makeText(context, "Hello Android.", Toast.LENGTH_SHORT).show(); } }
このような Handler の生成が必要な操作では Instrumentation.runOnMainSync() を利用します。 @RunWith(AndroidJUnit4.class) @LargeTest public class SimpleMenuPopupTest { @Test public void showToastTest() { InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { Context context = InstrumentationRegistry.getTargetContext(); Toast.makeText(context, "Hello Android.", Toast.LENGTH_SHORT).show(); } }); } } これでエラーにならなくなりました。


Dialog の場合、InstrumentationRegistry.getTargetContext() では Window Token が無いと言われてエラーになるので、ActivityTestRule から取得した Activity とかを使います。

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application


Espresso のコードはテストメソッドの方に書きます。 @RunWith(AndroidJUnit4.class) @LargeTest public class SimpleMenuPopupTest { @Test public void showPopupTest() { InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { Context context = activityRule.getActivity(); new AlertDialog.Builder(context) .setMessage("Hello Android.") .show(); } }); onView(withText("Hello Android.")).check(matches(isDisplayed())); } }


参考


0 件のコメント:

コメントを投稿