テスト補助ライブラリとしての RoboGuice 2.0

そもそも DI というものを知らない自分にとって、Android のテストを書く上で RoboGuice を活用しようと思ったときに、 最初にどう使えばいいのかわからず苦労したので、そのときのまとめ的なもの。

目的

テストを書くときに、あるオブジェクトをテスト用のモックのようなもので置き換えたい。 例えばネットワークアクセスをするようなクラスがあったとき、テスト時には実際にネットワークアクセスするのではなく、ダミーのレスポンスを設定できるようなもので置き換えてテストしたり、 常に失敗するようなもので置き換えて異常系のテストをしたりしたい。

準備

roboguice-2.0.jarguice-3.0-no_aop.jarjavax.inject-1.jar をメインプロジェクトの libs というディレクトリに入れておく。

メインプロジェクト

こっちの書き方はググればいくつか解説記事や StackOverflow のページが見つかる。 RoboGuice 固有の話は

  • アクティビティは android.app.Activity ではなく roboguice.activity.RoboActivity を継承するようにする。
  • 使う Module はリソースとして書く。例えば res/values/roboguice.xmlroboguice_modules という string-array として Module の完全なクラス名を並べる。

あたりか。

それ以外の DI の話は Guice について調べるといいと思う。 Guice の wiki は絶対に読む必要がある。

テストプロジェクト

テスト時に inject するオブジェクトを変えるには、テスト時に Module を切り替えればいい。 例えばテスト時には FakeModule を使いたい場合、 ActivityInstrumentationTestCase2 を使ったテストケースでは、setUp() か各テストケースで getActivity() を呼ぶ前に

  Context ctx = getInstrumentation().getTargetContext();
  Application app = (Application) ctx.getApplicationContext();
  Module m = Modules.override(RoboGuice.newDefaultRoboModule(app)).with(new FakeModule());
  RoboGuice.setBaseApplicationInjector(app, RoboGuice.DEFAULT_STAGE, m);

というような操作を行うことで達成できる。

一方、tearDown() では

RoboGuice.util.reset();

としておく。

 

これでだいぶテストが書きやすくなった。 けどそもそも Android のテスト環境は (まだ) 中途半端なもののように見えて、テスト書くのがむずかしい……