なか日記

一度きりの人生、楽しく生きよう。

Android Bindingを改めて使ってみた(2)

Android Bindingについて、前回のエントリで作成したアプリのテストはどうやるのがいいか考えてみました。

このエントリでの最終的なコミットはこちら
https://github.com/nakaji/AndroidBindingSample/commit/9fef17ef46bbcd73493497aa91c2d12bb7746ba3

テスト対象

テストの対象となる部分は大きく以下の2つに分かれます。

  1. BMI計算に関するロジック
  2. UI周り
BMI計算に関するロジック

ViewとViewModelに分離していますので、ここでテストする対象はViewModelとなります。これをJUnitでテストするにはどうすればいいのか?というのがこのエントリの目的です。

UI周り

ロジックについてはViewModelのテストで保証されているので、ここでは主に「ViewとViewModelのバインドがちゃんと行えているか」という観点でのテストになります。
こればっかりはエミュレータや実機等で実際に操作するしか今の自分にはできません。AndroidのテストプロジェクトやMonkeyRunnerなど使って自動化できそうですが、今の私にはそこまでの知識はないので、またそのうち…

どうテストするか

CommandクラスのInvokeメソッドの引数でAndroid固有のViewクラスを使用しているので、通常のクラスとしてのテストは難しそうです。
以前のエントリで触れたRobolectricを使用すればAndroidエミュレータを使用せずにテストできそうです。

そもそも

ViewModelの中でViewクラスは参照していますが、そのクラスのインスタンスを生成したり、メソッドを呼び出していないので、エミュレータ上じゃなくても動くんじゃないの?という気がしてきました。

試してみた内容

  1. Javaプロジェクト(BMICalcTest)を作成
  2. Javaのビルド・パスに以下を追加
    • BMICalcプロジェクト
    • android-binding-0.45-update.jar
    • android.jar
  3. JUnitテストクラスを作成してテスト実行
Javaのビルド・パスにandroid.jarを追加

Invokeメソッドで使われてるViewクラスの解決が行えないので、Windows環境であれば \android-sdk-windows\platforms\android-10 等の配下にある android.jar をビルドパスに追加しておきます。

JUnitテストクラスを作成してテスト実行

以下のようなテストクラスを作成しました。

public class BMIViewModelTest {
    private BMIViewModel viewModel;

    @Before
    public void setUp() {
        viewModel = new BMIViewModel();
    }

    @Test
    public void Calc() {
        viewModel.height.set("172");
        viewModel.weight.set("60");
        viewModel.Calculate.Invoke(null, (Object[]) null);

        Assert.assertEquals(60 / Math.pow(172 / 100.0, 2), viewModel.BMI.get());
    }
}

ViewModel側で実装したInvokeメソッドでは引数に渡されたViewを使用していませんので、ここではあえてnullを渡しています。
逆に、Invokeメソッドで使用してしまうとテストコード内でViewのインスタンスを生成することになりますので、Androidのテストプロジェクトを使用する必要が出てきます。そうなると本来の目的を満たせないのでダメ。ゼッタイ

テスト実行結果

テスト実行するとちゃんとグリーンになりました。
f:id:nakaji999:20111226154127p:image:w640

所感

PojoViewModelでシンプルに実装できるのが一番いいのかもしれませんが、片方向しかバンドできないのはやっぱりメリットが少ないと感じました。今回のようなやり方ででも双方向バインドが行えるライブラリを使った方がコードもすっきりするし、個人的には好きかな。と個人で野良アプリしか作ったことのない私は思ってみる。