JUnitとMockitoを用いたJavaにおけるライティングユニットテスト


記事は、もともとUsing jUnit and Mockito for unit testing in Javaの下で私の個人的なウェブサイトに掲示されます
テストはすべてのソフトウェアシステムとアプリケーションにとって重要です.それはあなたが簡単にバグを見つけるのに役立ちます、そして、特にシステムが時間とともに進化するならば、それはあなたのアプリケーションのために衝突とダウンタイムを防止します.最初に、それは重要に見えないかもしれません、しかし、システムが成長して、より複雑になるように、注目されることなく現れているバグの可能性は成長します.
Javaで利用可能な複数のテストフレームワークがあります.この論文では、JUnitが提供するいくつかの簡単なAPIと、単体テストのためにそれらを使用する方法を調べていきます.ほとんどの場合、JUnitは十分でなく、コンボjunit + mockitoはしばしば見つかります.
知っていない人のために、mocKitoはあなたがテストするクラスを簡単に分離することができて、クラスによって使用されている他のクラスまたは構成要素の出力をコントロールすることができるように、あなたが特定のクラスをモックするテストのために使われるもう一つのフレームワークです.また、モックが呼び出されたかどうかを確認する可能性を提供しています、何回、他の便利な機能.

JUnitでの結果の妥当性検査


単体テストでのシンプルで最も広く使われている機能は、受信した結果が期待されるものであることをチェックしています.これは、あなたのメソッドが実際に正しい答えを返すことを確認するために必須であるため、頻繁にテストを書くときに使用される基本的な機能です.これは

 methods.



```java
@Test
public void aSimpleTest() {
    int aNumber = 5;
    String str = "A test string";
    double aDouble = 4.67;

    Assert.assertEquals(5, aNumber);
    Assert.assertEquals("A test string", str);
    Assert.assertEquals(4.67004, aDouble, 0.001);
}
ダブル変数の主張に注意してください.数字が本当に等しくないにもかかわらず、テストはまだ通過します.これは、メソッドの最後のパラメーターが精度を表すためです.これは、我々が結果を許容して、まだそれが有効であると考えている逸脱です.あなたがより良い精度を望むならば、ちょっとデルタを小さくしてください.

カスタムエラーメッセージ


テストが失敗した場合にカスタムメッセージを表示することが重要です.この機能は、完全なスタックトレースへのアクセスが取得するのは難しい自動ビルド中に多くの時間を節約できます.あなたが簡単に何が間違っていたかを印刷することができますカスタムメッセージを使用して、どの変数が正しくなかったか、または(または他のエンジニア)が何が起こったかを理解するのに役立つすべての情報を.これは、最初にmessageパラメータを持つassertのオーバーロードされたメソッドを使用して、以下に示すようにします.
@Test
public void aSimpleTestWithMessage() {
    String myStr = "This test will fail";
    Assert.assertEquals("The myStr variable is not the expected value", "Nothing", myStr);
}

JUnitにおける複雑オブジェクトによる結果の検証


ほとんどの場合、複数のフィールドを持つ複雑なオブジェクトがあります.それは簡単なもののようにそれらをチェックするのは簡単です.JUnitは、equals ()メソッドを使用して、受信した結果が予想されるものと同じであることを確認します.そういうわけで、この場合、あなたのオブジェクトのためにきちんと書かれたequals ()メソッドが重要です.このデータクラスを見てみましょう.
public class DataClass {
    private String field1;
    private String field2;
    private int field3;

    public DataClass(String field1, String field2, int field3) {
        this.field1 = field1;
        this.field2 = field2;
        this.field3 = field3;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DataClass dataClass = (DataClass) o;
        return Objects.equals(field1, dataClass.field1)
                && Objects.equals(field2, dataClass.field2)
                && Objects.equals(field3, dataClass.field3);
    }
}
さて、テストを書くことができ、equals ()メソッドが正しく書き込まれるため、2つの異なるオブジェクトがあってもテストはパスします.
@Test
public void testComplexObject() {
    DataClass obj1 = new DataClass("f1Value", "f2Value", 3);
    DataClass expected = new DataClass("f1Value", "f2Value", 3);

    Assert.assertEquals(expected, obj1);
}
しかし、あるシナリオでは、まったく同じオブジェクトが返されることを確認したい.これはassertを使って実現される.SAME ()メソッドそれはアサートのように正確に動作します.しかしながら、AsserteQuest ()は、その内容を等しくチェックしません.それを使用して、予想と結果が同じならば、テストは通過します.

JUnitで例外の妥当性検査がスローされます


別の便利な機能は、無効な入力が受信されたときに、このメソッドが実際に適切な例外をスローすることを検証します.これを行うには複数の方法がありますが、簡単に期待されるパラメータを提供することです
注釈.これはJUnitにテストが正しいならば、与えられた例外をスローすると伝えます.
@Test(expected = NumberFormatException.class)
public void testNumberParse() {
    Integer.parseInt("a");
}

モッキトを使ってあなたの反応をモックする方法


複雑系は互いに相互作用する複数の構成要素とクラスを有する.このようなシステムでは、一度にすべてをテストするのは難しいです.なぜなら、それぞれのコンポーネントがどのように動作するのかを知らないからです.だからこそ、モックの概念が導入されている.MOCKはあなたのクラスのAPIを複製するオブジェクトですが、どんな処理もしません.代わりに、単にあなたがそれを指示するものを返します.
これは単体テストに便利です.なぜなら、クラスで使用される他のオブジェクトの内部動作を無視しながら、1つのクラス(実際にテストしたいもの)に集中できるからです.例として、サービスをテストし、集約が正しいかどうかを検証したいと仮定します.サービスは、データベースから生データを取得するために1つまたは複数のDAOSを使用します.あなたはDBに書かれたデータを持っていたくないし、毎回DBを打つことによって遅いテストをしたくない.
あなたがこのケースで何をするかは、DAOSを模擬して、モックに各々のテストのために何を返すかについて話します.これは簡単にmockitoを使用して行われます.
private static MyDao mockDao;

@BeforeClass
public static void setup() {
    // Initialize the mock of the type MyDao
    mockDao = Mockito.mock(MyDao.class);
}
さて、お使いのサービスに設定することによってテストを書くことができます(setterを使用するか、依存性注入機構を使用して)、DOが呼び出されるときに何を返すかを指定します.こちらがオリジナルです.DAOがまだ書かれていなくても、サービスが動作することをテストしたいと思います.
public class MyService {
    private MyDao dao;

    public void setDao(MyDao dao) {
        this.dao = dao;
    }

    public boolean process(String id) {
        if (id == null) return false;

        List<DataClass> all = dao.getAll();
        if (all == null || all.isEmpty()) return false;

        DataClass ofInterest = dao.get(id);
        if (ofInterest == null) return false;

        // do some processing
        return true;
    }
}
public class MyDao {
    public List<DataClass> getAll() {
        return Collections.emptyList();
    }

    public DataClass get(String id) {
        return null;
    }

    public void save() {
        // do nothing
    }
}
私たちは、私たちのサービスのためのオブジェクトとしてmock daoを設定し、それが呼び出されたときに適切なデータを返すように指示します.このようにして、テストの実行だけでなく、開発もスピードアップします.
@Test
public void testService() {
    MyService service = new MyService();
    service.setDao(mockDao);

    Mockito.when(mockDao.getAll()).thenReturn(Arrays.asList(new DataClass("a", "b", 3)));
    Mockito.when(mockDao.get(Mockito.eq("a"))).thenReturn(new DataClass("a", "b", 4));

    boolean result = service.process("a");
    Assert.assertEquals(true, result);
}
モッカトget ()メソッドは、呼び出されたときに何を返すかをモックに伝えます.また、指定したヘルパーメソッドを使用してパラメーターを持つメソッドを期待するパラメーターを指定できます.EQ , Mockto何でも、mockito.マッチ、mockito.同様.

試験データの準備と清掃


複雑なシステムでは、いくつかのテストが複雑になり、コードの他のシステムや部分との相互作用が必要になります.いくつかのテストデータを記述する必要がある、いくつかの機能や機能をオンまたは単にいくつかの環境変数を設定する必要があります.テストはスイートでテストすることができます.または、JUnitの前と後の機能を使用して、すべてが正しく初期化され、クリーンアップされるようにすることができます.
JUnitは、これに役立つ4つの重要な注釈を持っています:@と@ beClassassは、後に@そして@ afterclassと並んでいます.
@ beforeで注釈されるメソッドは、クラスの各テストの前に実行されます.テストクラスの場合、複数のメソッドを使用して注釈を付けます
@ beforeは、各テストメソッドが実行される直前に実行されます.同様に、@ afterはスーツの各テストの後に実行されます.
他の2つの注釈は、@ beexplassと@ afterclassは一度だけ、正確にすべてのテストが実行される前に実行されると、テストの結果に関係なく、すべてのテストが終了した後.これらのメソッドは、環境を準備したり、任意のテストデータを書くだけでなく、環境を保証するために必要なクリーンアップを行うために非常に便利ですが、環境がきれいな状態では、データをぶらぶらしています.

結論


見られるように、JUnitとMockitoの助けを借りてJavaは、あなたのコードのユニットテストを書くために必要なすべての必要な機能と機能を提供します.それは不便として見えるかもしれないが、よく書かれたテストを持っている場合、迅速かつだけでなく、堅牢で安定したソフトウェアシステムを維持するバグを識別するのに役立ちます.
いつものように、私の個人的なウェブサイト上で完全なサンプルコードをダウンロードすることができます.
記事は、もともとUsing jUnit and Mockito for unit testing in Javaの下で私の個人的なウェブサイトに掲示されます