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()

になります。
  1. @RunWith(AndroidJUnit4.class)  
  2. @LargeTest  
  3. public class SimpleMenuPopupTest {  
  4.   
  5.     @Test  
  6.     public void showToastTest() {  
  7.         Context context = InstrumentationRegistry.getTargetContext();  
  8.         Toast.makeText(context, "Hello Android.", Toast.LENGTH_SHORT).show();  
  9.     }  
  10. }  

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


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

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


Espresso のコードはテストメソッドの方に書きます。
  1. @RunWith(AndroidJUnit4.class)  
  2. @LargeTest  
  3. public class SimpleMenuPopupTest {  
  4.   
  5.     @Test  
  6.     public void showPopupTest() {  
  7.         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {  
  8.             @Override  
  9.             public void run() {  
  10.                 Context context = activityRule.getActivity();  
  11.                 new AlertDialog.Builder(context)  
  12.                         .setMessage("Hello Android.")  
  13.                         .show();  
  14.             }  
  15.         });  
  16.   
  17.         onView(withText("Hello Android.")).check(matches(isDisplayed()));  
  18.     }  
  19. }  



参考


0 件のコメント:

コメントを投稿