LoginSignup
21
21

More than 5 years have passed since last update.

Robolectric を 3.0 にアップデートするときにハマる箇所

Last updated at Posted at 2015-08-03

公式のやることリスト

公式が Wiki にガイドを用意してくれています。基本的にはこのガイドに従ってアップデートしていきます。

足りない部分

しかしアプリケーションによっては足りない部分があり、テストがテストケースとは関係ない部分でバッタバッタと死んでいく事があります。

1. targetSdk が 22 で落ちる

現状 Robolectric 3.0 で対応しているのは 21 までです。targetSdkVersion を 22 にしていると、UnsupportedOperationExceptionでテストができません。

対応するには、@Configアノテーションでバージョンを指定します。


@Config(constants = BuildConfig.class, sdk = 21)
public class SomeTest {}

2. MultiDex で落ちる

Multidex を使っているプロジェクトでは、MultidexApplicationを継承したApplicationクラスを用意するか、MultidexApplicationをそのまま使用するか、どちらかをすることになりますが、attachBaseContext()内でのMultidex#install()はテストからはうまく実行できず例外で落ちます。

テストでは Multidex は関係ないので、例外を吐こうが影響はないですから、例外をキャッチするようにします。サポートライブラリのMultidexApplicationを使用している場合、そちらのコードを丸パクリして try-catch 句を追記したクラスを自分で用意します。


public class MultidexApplication extends Application {
  @Override
  protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);

    try {  // avoid robolectric error
      MultiDex.install(this);
    } catch (RuntimeException ignored) {
      // ok to ignore exception while testing
    }
  }
}

3. AndroidManifest やその他のリソースが見つからなくて落ちる

ApplicationId をビルドスクリプトで指定していて、それが実際のパッケージ構成と違う場合に起きるものです。すべてのテストで Resources$NotFoundException が出てきて、謎のリソースを参照しようとして無いと怒られるようなパターンはこれです。

パッケージ名を指定する設定が@Configアノテーションにはありますが、そうするとこんどは ResourceLoader が見つからないという理由でテストがクラッシュします。

さくっと解決するならば、以下のようなTestRunnerを用意してしまうことでテストが動くようになります。


public class MyTestRunner extends RobolectricGradleTestRunner {
  public MyTestRunner(Class<?> testClass) throws InitializationError {
    super(testClass);
  }

  @Override
  protected AndroidManifest getAppManifest(Config config) {
    return new AndroidManifest(
        Fs.fileFromPath("../DriveMode/src/main/AndroidManifest.xml"),
        Fs.fileFromPath("../DriveMode/build/intermediates/res/" + BuildConfig.FLAVOR + "/debug"),
        Fs.fileFromPath("../DriveMode/build/intermediates/assets/" + BuildConfig.FLAVOR + "/debug/"));
  }
}

すべてのテストで以下のように@RunWithを指定すれば完了です。


@Config(constants = BuildConfig.class, sdk = 21)
@RunWith(MyTestRunner.class)
public class SomeTest {}

これで、すべてのテストが一律同じ理由でバッタバッタと死んでいく現象は解消されます。

21
21
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
21