検索
連載

Android Mockを利用してHTTP通信をテストするにはAndroidアプリ開発テスト入門(5)(3/3 ページ)

日本Androidの会テスト部が、いままで培ってきたAndroidアプリ開発におけるテストのノウハウを、実際のテストコード例とともに紹介していきます

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

モックに対する操作を検証するには

 先のテストコードの最後に、以下のように書かれていました。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 「verify()」は、モックにあらかじめ定義したメソッドがすべて呼ばれたことを検証し、定義と異なる使われ方をしていた場合に例外を発生してテストを失敗させます。

 コメントに「冗長な確認」と書いていますが、これは筆者が「あまりverify()に頼らないように」するための戒めです。テスト対象メソッドの実装にまで踏み込んだ検証を乱用すると変更に弱いテストコードになってしまうので、verify()による検証は補助手段に留めるべきでしょう。

 verify()の検証内容は、モックの生成時点で以下の3パターン存在します。

  1. createMock()で生成したモック
    expect()で指定したメソッドの呼び出し順はチェックされないが、expect()されていないメソッドを呼び出すと例外を発生し、テストを失敗させる
  2. createNiceMock()で生成したモック
    最も制限の緩いモック。expect()で指定したメソッドの呼び出し順はチェックされず、またexpect()していないメソッドを呼び出されても例外は発生ない(型に応じて「0」「false」「null」のいずれかが返る)
  3. createStrictMock()で生成したモック
    メソッドの呼び出し順まで厳密に検証されるモック。expect()順と異なる順序でメソッドを呼ばれた時点で例外を発生し、テストを失敗させる

 いずれもverify()では、expect()されたにもかかわらず呼び出されていないメソッドが残っていると例外を発生してテストを失敗させます。StrictMockの利用例をHTTP通信の正常系テストケースから抜粋して紹介します。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 このように定義していると、getStatusLine()を呼び出さずに(つまり、HTTPステータスを確認せずに)getEntity()で本文を取得しているコードを検出できます。

コラム 「Test Double Pattern」とは

記事中ではモックオブジェクトと表現していますが、モックの定義や分類には、さまざまな流儀があります。

著名なユニットテストの実装パターン集である『xUnit Test Patterns(および同名の書籍)』では、これを「Test Double」と総称したうえで、テスト対象への間接入力を操作する「Test Stub」、テスト対象からの間接出力を受け取り記録する「Test Spy」、また間接出力の検証までオブジェクト内で行う「Mock Object」などに分類しています。

興味を持たれた方は、ぜひ原書や読書会のログなどを読んでみてください。


次回は継続的インテグレーションをAndoridテストに

 今回はHTTP通信という外部要因のテストのためにモックを使用する方法を紹介しましたが、モックオブジェクトは「テスト対象が依存するコンポーネントをモックに置き換えてテストする」テクニックであり、テスト対象をクリーンな環境で確実にテストする目的で広く適用できます。

 HttpClientに限らず、DateやPreferencesなど、モックオブジェクトを導入することでユニットテストが可能になる範囲は広がるはずです。これは次回紹介するCIの導入において前提ともいえるので、ぜひ導入を検討してみてください。

 ただし、過度にモックを多用、依存することはテストコードの保守性を低下させます。適用すべき個所を見極めて、良いテストコードを書きましょう。

 なお、本稿で掲載したソースコードは以下のリポジトリで公開されています。

著者紹介

Androidテスト部

長谷川 孝二(@nowsprinting

元メーカー系、現在フリーランス(個人企業法人)のエンジニア。これまでサーバサイドから携帯電話まで大小のJava案件にかかわり、現在はiOS/Androidアプリの請負開発が主軸。

自作アプリ『山吹色の茸疾走』のロジック強化が最近の息抜き



Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る