visible true

技術的なメモを書く

Data BindingのテストはAndroid5.0以上の環境じゃないと動かない

※ 2015/06/28 20:31追記 ART環境だったら動きました。4.4系でもRuntimeをARTにしておけばテスト動きます

問題

具体的にはこんなコードです。

@Test
public void test() {
  //XXXBindingはData Bindingで生成したクラスです
  XXXBinding binding = XXXBinding.inflate(LayoutInflater.from(
      InstrumentationRegistry.getTargetContext()
  ));
  assertThat(binding, is(notNullValue()));
}

ActivityMvvmBinding.inflate()の所で以下のエラーが出ます。

java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation

原因?

ClassLoaderの関係で問題が起きているようです。テストコードをビルドするとテストプロジェクト側でもData Binding用のクラスが生成されます。これによりテスト側のXXXBindingとアプリケーション側のXXXBindingが異なりエラーが起こっているようです。が正確にはわかりません。

対応

issue trackerに以下の投稿がありました。

Issue 177588 - android - Android Studio AI.141 DataBinding test - Android Open Source Project - Issue Tracker - Google Project Hosting

その中で「環境の問題だったわー」という会話がされています。投稿者のSample CodeにはTest could not run Below android 5.0 !!という文言が更新されてました。

Android5.0以上で実行しなければならないようですね!!!早速エミュレータを使って実行してみます。次はこんなエラーが。

java.lang.IllegalStateException: DataBinding must be created in view's UI Thread

なるほどUIスレッドじゃないとダメなようです。これはもう簡単ですね。最終的に以下のコードとなりました。

@Test
public void test() {
  InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
    @Override
    public void run() {
      ActivityMvvmBinding binding = ActivityMvvmBinding.inflate(LayoutInflater.from(
          InstrumentationRegistry.getTargetContext()
      ));
      assertThat(binding, is(notNullValue()));
    }
  });
}

まとめ

  • Data Bindingを使ったテストはAndroid5.0以上の環境で実行するべし(※ 2015/06/28 20:31追記 ART環境だったら動きました。4.4系でもRuntimeをARTにしておけばテスト動きます)
  • XXXBindingはUI Threadで触る必要がある。Instrumentation#runOnMainSync(Runnable)などを使おう
  • XXXBindingのテストを書くとActivityとか無しでActivityの状態変化のテストができて便利ですね?