任意のオブジェクトをモック化するテストメソッド作成

任意のオブジェクトをモック化するテストメソッド作成

単体テストアシスタントはテストメソッドの作成後、任意のインタフェースやオブジェクト、メソッドの戻り値をモック化してテストを行うことができます。

Cart#getItemDB メソッドをテストするメソッドを作成します。

テストメソッド作成

  1. ソースコードペインで Cart#getItemDB メソッドを開きます。



  2. 単体テストアシスタントビューで

    を押下します。



  3. テストメソッドテンプレートは UTA プロジェクトの tests フォルダに作成されます。

    基本的な単体テストの実施で CartTest.java を既に作成している場合、同じクラスファイル内に testGetItemDB() メソッドが追加されます。
    (テストメソッド名は連番で付けられるため本チュートリアルの実施順によって異なります。)

テストメソッド確認

  1. 作成されたテストメソッドテンプレートの内容を確認します。

    @Test public void testGetItemDB() throws Exception { // テストメソッド // Given Cart underTest = new Cart(); // テストインスタンスの生成 // When // getItemDB メソッドの引数 Connection con = null; // UTA: デフォルト値 String itemId = ""; // UTA: デフォルト値 Item result = underTest.getItemDB(con, itemId); // getItemDB メソッドの呼び出し // Then // assertNotNull(result); // getItemDB の戻り値のチェック用アサーションテンプレート }

    テンプレート作成時に getItemDB(Connection, String) メソッドの引数となるConnection オブジェクトと String オブジェクトにはそれぞれのデフォルト値が格納されます。
    Connection オブジェクトのデフォルト値には null が格納されるため、getItemDB(Connection, String) メソッドで Connection オブジェクトにアクセスすると、 java.lang.NullPointerException が発生します。

    Connection オブジェクトのモックを作成し getItemDB(Connection, String) にはモックオブジェクトが渡されるようにコードを変更します。(モックの作成は次の任意のオブジェクトをモック化で行います。)

    getItemDB(Connection, String) メソッドの String 引数を入力します。

    次のコードの “” を “001” に変更します。

    変更前 String itemId = ""; 変更後 String itemId = "001";

    変更後のファイルを保存し、プロジェクトのビルドが正常に行われることを確認します。

任意のオブジェクトをモック化

getItemDB(Connection, String) メソッドの引数 Connection オブジェクトをモックオブジェクトに変更します。

  1. testGetItemDB() メソッドの Connection オブジェクトをダブルクリックで活性化し、単体アシスタントビューの

    をクリックします。

    Connection オブジェクトが活性化されていない場合メニューに
    が表示されません。メニューが表示されていない場合は、ソースコード上で活性化されている内容を確認してください。Connection オブジェクトが以下のようにモックオブジェクトに変更されたことを確認します。

    変更前 変更後 Connection con = null; ⇒ Connection con = mock(Connection.class);
  2. 変更後の testGetItemDB() メソッドを

    から実行します。

  3. 実行結果を確認します。

    ● JUnitビュー


    実行時に java.lang.NullPointerException が発生したことにより、テストがエラーとなったことがわかります。
    ● 推奨事項ビュー例外/アサーション エラーの情報が出力されていることを確認します。


    推奨事項内の  
    をクリックし、単体テストアシスタントビューの実行フローで例外が発生したコードがハイライトされることを確認します。

    ハイライトされた内容を確認すると getItemDB(Connection, String) メソッドで以下のコードの実行時に例外が発生したことがわかります。

    そのため、Statement オブジェクトをモックオブジェクトに変更します。

推奨事項からモック化

Statement オブジェクトのモック化は推奨事項タブに表示されている推奨事項から行います。
事前操作として、推奨事項ビューで 例外/アサーション エラーでハイライトが有効になっている場合は、

でハイライトを解除します。

  1. 推奨タブに表示される モックの情報を確認します。


    Statement オブジェクトをモックするためのアクションが表示されていますので  
    をクリックします。

  2. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認します。

    Statement createStatementResult = null; when(con.createStatement()).thenReturn(createStatementResult);

    Connection#createStatement() はモック化され任意の戻り値を返却できるようになりました。

    続いて、Connection#createStatement() の戻り値となる Statement オブジェクトをモック化します。
    testGetItemDB() メソッドの Statement オブジェクトをダブルクリックで活性化し、単体アシスタントビューの

     をクリックします。



    Statementオブジェクトが以下のようにモックオブジェクトに変更されたことを確認します。

    変更前 変更後 Statement createStatementResult = null; ⇒ Statement createStatementResult = mock(Statement.class);

    このコードの追加により、testGetItemDB() メソッドの実行時に con.createStatement() が呼び出された場合、モックオブジェクトの Statement オブジェクトが返却されます。

  3. 変更後の testGetItemDB() メソッドを

    から実行します。

  4. 実行後 Junit ビュー、単体テストアシスタントビューではlang.NullPointerException の発生と ResultSet オブジェクトのモック化を推奨する情報が出力されていることが確認できます。


    推奨事項に合わせて ResultSet オブジェクトもモックオブジェクトに変更します。

  5. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認します。

    ResultSet executeQueryResult = null; when(createStatementResult.executeQuery(nullable(String.class))). thenReturn(executeQueryResult);

    ResultSet#executeQuery() はモック化され任意の戻り値を返却できるようになりました。

    続いて、ResultSet#executeQuery() の戻り値となる ResultSet オブジェクトをモック化します。
    testGetItemDB() メソッドの ResultSet オブジェクトをダブルクリックで活性化し、単体アシスタントビューの  

    をクリックします。

  6. 変更後の testGetItemDB() メソッドを

    から実行します。

  7. 実行後 Junit ビューではテストが正常に終了していること、単体テストアシスタントビューでも例外が発生していないことを確認します。
    一方で モック の推奨事項が表示されていることがわかります。


     のクリックで実行フローを確認すると getItemDB(Connection, String) メソッドの if 分岐のモック化を推奨していることがわかります。

    ここまでに ResultSet オブジェクトをモックオブジェクトに変更しているため、testGetItemDB() メソッドの実行による getItemDB(Connection, String) メソッドの呼出し時に if 分岐条件が true となることはありません。
    そのため、rs.next() メソッドの戻り値をモック化する推奨事項が表示されています。

  8. 推奨事項の

    をクリックしnext() をモック化します。

  9. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認します。

    boolean nextResult = false; // UTA: デフォルト値 when(executeQueryResult.next()).thenReturn(nextResult);

    このコードの追加により、testGetItemDB() メソッドの実行時に rs.next() メソッドの呼出し時にモックオブジェクトが返却されます。 if 分岐において true となるようにコードを変更します。

    変更前 boolean nextResult = false; boolean nextResult = true;
  10. 変更後の testGetItemDB() メソッドを

    から実行します。

  11. 実行後、単体テストアシスタントビューで“モック” の推奨事項が表示されていることがわかります。



    この推奨事項はそれぞれ getItemDB(Connection, String) メソッドの以下のコードに対して出力されています。

    今回は ResultSet オブジェクトをモック化しているため、 rs.getString(String) メソッドおよび rs.getInt(String) メソッドの戻り値はそれぞれ null または 0 となります。

    getItemDB(Connection, String) メソッド呼び出し時にテストデータを返却するよう推奨事項に合わせてモック化します。

  12. 1つ目の推奨事項の

    をクリックし、モックオブジェクトを作成します。

  13. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認し、変更します。

    追加直後 String getStringResult = ""; // UTA: デフォルト値 when(executeQueryResult.getString(nullable(String.class))).thenReturn(getStringResult); 変更後 String getStringResult = "商品A"; when(executeQueryResult.getString("name")).thenReturn(getStringResult);
  14. 2つ目の推奨事項の

    をクリックし、モックオブジェクトを作成します。

  15. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認し、変更します。

    追加直後 String getStringResult2 = ""; // UTA: デフォルト値 when(executeQueryResult.getString(nullable(String.class))).thenReturn(getStringResult2); 変更後 String getStringResult2 = "001"; when(executeQueryResult.getString("id")).thenReturn(getStringResult2);
  16. 3つ目の推奨事項の

    をクリックし、モックオブジェクトを作成します。

  17. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認し、変更します。

    追加直後 int getIntResult = 0; // UTA: デフォルト値 when(executeQueryResult.getInt(nullable(String.class))).thenReturn(getIntResult); 変更後 int getIntResult = 100; when(executeQueryResult.getInt("price")).thenReturn(getIntResult);
  18. 4つ目の推奨事項の

    をクリックし、モックオブジェクトを作成します。

  19. testGetItemDB() メソッドに以下の 2 行が追加されたことを確認し、変更します。

    追加直後 int getIntResult2 = 0; // UTA: デフォルト値 when(executeQueryResult.getInt(nullable(String.class))).thenReturn(getIntResult2); 変更後 int getIntResult2 = 10; when(executeQueryResult.getInt("count")).thenReturn(getIntResult2);