JUnitとは何か?初心者向け入門ガイド

公開日: 2023/6/19 更新日: 2023/5/12

Junitは、Java言語用のオープンソースの単体テストフレームワークです。

単体テストは、プログラムの各部分が個別に正しく動作するかを確認するために行われます。

Junitは、テスト駆動開発(TDD)と呼ばれるアジャイルソフトウェア開発の手法をサポートするために開発されました。


Junitは、テストケースの定義、テストの自動実行、テスト結果のアサーション(検証)など、テストに必要な機能を提供します。

また、テスト結果のレポーティング機能も備えています。


Junitは、プログラマーにとって非常に便利なツールであり、プログラムの品質を向上させるために欠かせないものとなっています。

Junitを使用することで、プログラムの変更がもたらす影響をすばやく確認することができます。

1. STS4(Spring Tool Suite 4)でJunitを使用する


Junitを使用するために、STS4(Spring Tool Suite 4)にJunitを統合する必要があります。

1-1. 事前準備

以下は、STS4でJunitを使用するための手順です。

1.STS4を開き、プロジェクトを作成、または開きます。
2.プロジェクトを右クリックして、[Build Path] -> [Add Libraries]を選択します。


3.[Add Library]ウィンドウで、[JUnit]を選択し、[Next]をクリックします。


4.使用するJUnitバージョンを選択します。STS4には、JUnit 4と5の両方が含まれています。


5.ビルドパスにJUnitライブラリが追加されたら、テストケースを作成してJunitを使用できます。


1-2. テストケースを作成する

Junitを使用するには、テストクラスを作成する必要があります。

テストクラスは通常、テストしたいクラスと同じパッケージに作成されます。

以下は、テストクラスの作成手順です。

1.パッケージエクスプローラーで、テスト対象のクラスが含まれるパッケージを右クリックし、「New」>「JUnit Test Case」を選択します。


2.「New JUnit Test Case」ダイアログが表示されます。

ダイアログで以下を設定します。

・Package: テストクラスを作成するパッケージ名
・Name: テストクラスの名前
・Kind: JUnit4を選択します
・Class under test: テスト対象のクラスを選択します


3.「Finish」をクリックします。

4.テストクラスが作成されます。
以下は、作成されたテストクラスの例です。


この例では、MyTestという名前のテストクラスが作成されています。

テストクラスには、テストケースの各メソッドが含まれます。

テストケースのメソッドには、@Testアノテーションが付けられます。

この例では、testという名前のテストケースメソッドが定義されています。


1-3. アサーションを使用してテストを作成する

1.テストするメソッドを作成する

    public static int myMethod(int x, int y) {
        return x + y;
    }


テスト対象のメソッドが以上だった時は、テストクラスに次のようなテストメソッドを作ります。

    @Test
    public void testMethod() {
    }


2.テストするコードを記述する

@Test
public void testMethod() {
    int result = MyClass.myMethod(3, 4); // MyClass.myMethodはint型の値を返すメソッド
    assertEquals(7, result); // 期待される値と実際の値が等しいことを検証する
}

このコードは、テストされるメソッドの正しい動作を検証するための入力値を設定し、メソッドを呼び出して返された値を検証するコードを含みます。

JUnitには、多くのアサーションがありますが、assertEqualsメソッドは特によく使われます。このメソッドは、2つの引数が等しいことを検証します。

1-4. テストの実行

アサーションを使用したテストを作成した後は、テストランナーによりテストを実行して、テストがパスするかどうかを確認する必要があります。

テストを実行するには、テストクラスを右クリックして、「Run As」→「JUnit Test」を選択するか、EclipseのJUnitビューでテストクラスを選択し、「Run」ボタンをクリックします。


テスト実行中に、JUnitはテストが成功したか失敗したかを報告するために、グリーンのバー(成功)または赤のバー(失敗)を表示します。

テストに失敗した場合、エラーメッセージが表示されます。

これを使用して、テストが失敗した理由を特定し、テストコードを修正する必要があります。


2. ライフサイクルメソッド

@TestはJUnitにおいてテストメソッドと呼ばれます。

一方、JUnitにおけるライフサイクルメソッド(Lifecycle Method)とは、テストメソッドの前後に実行されるメソッドのことです。

これらのメソッドを利用することで、テストのセットアップやクリーンアップ、リソースの解放など、テストの前後処理を行うことができます。

@Before

@Before
public void setUp() {
    // テストメソッドの前に実行される処理を記述する
    // 例えば、テストデータの準備や初期化処理など
}

@After

@After
public void tearDown() {
    // テストメソッドの後に実行される処理を記述する
    // 例えば、テストデータの後片付けやリソースの解放など
}

3. アサーション

アサーションとは、テストコード内で期待される振る舞いを定義するための命令です。

具体的には、ある条件が満たされていることを確認するために使用します。

アサーションは、テストメソッド内で使用され、通常、実際の値と期待する値を比較することで機能します。


以下はJUnitにおける代表的なアサーションと、その記述例です。

assertEquals(expected, actual)

期待される値expectedと実際の値actualが等しいことを検証します。

int expected = 5;
int actual = MyClass.myMethod(2, 3);
assertEquals(expected, actual);

assertNotEquals(expected, actual)

期待される値expectedと実際の値actualが等しくないことを検証します。

int expected = 5;
int actual = MyClass.myMethod(2, 3);
assertNotEquals(expected, actual);

assertTrue(condition)

条件conditionがtrueであることを検証します。

boolean condition = MyClass.isPositive(2);
assertTrue(condition);

assertFalse(condition)

条件conditionがfalseであることを検証します。

boolean condition = MyClass.isPositive(-2);
assertFalse(condition);

assertNull(object)

オブジェクトobjectがnullであることを検証します。

Object object = MyClass.getObject(null);
assertNull(object);

assertNotNull(object)

オブジェクトobjectがnullでないことを検証します。

Object object = MyClass.getObject(new Object());
assertNotNull(object);

assertSame(expected, actual)

期待されるオブジェクトexpectedと実際のオブジェクトactualが同じインスタンスであることを検証します。

Object expected = MyClass.getObject();
Object actual = MyClass.getObject();
assertSame(expected, actual);

assertNotSame(expected, actual):

期待されるオブジェクトexpectedと実際のオブジェクトactualが異なるインスタンスであることを検証します。

Object expected = MyClass.getObject();
Object actual = new Object();
assertNotSame(expected, actual);

assertThat(actual, matcher)

Hamcrestライブラリを使用して、actualがmatcherに一致することを検証します。

String actual = "test string";
assertThat(actual, is(notNullValue()));
assertThat(actual, is(insta

4. モック

プログラムのテストにおいて、テスト対象のメソッドが依存するオブジェクトを置き換えることで、テスト対象のメソッドを単独でテストするための仮想オブジェクトのことをモックと呼びます。

モックは、テスト対象のメソッドが実際のオブジェクトと同じように動作するように、必要なメソッドを実装します。

モックは、テスト時に予測不能な結果を回避するためにも役立ちます。

4-1. Junitにおけるモック

Junitでのモックは、モックライブラリを使用する方法が一般的です。

モックライブラリを使用すると、手動でモックオブジェクトを作成する必要がなく、より効率的にモックを作成および管理できます。

また、多くの場合、モックライブラリにはモックの検証を行うための機能も含まれています。

ただし、プロジェクトの特定のニーズに合わせて、手動でモックオブジェクトを作成する方法が適切な場合もあります。


以下は、Mockitoというモックライブラリを使用した、モックオブジェクトの実装例です。


・まず、テストしたいクラスが依存しているオブジェクトをインタフェースで定義します。

例えば、以下のようなインタフェースがあるとします。

public interface DataService {
    List getNames();
}


・次に、テストするクラスでこのインタフェースを使用するようにします。

例えば、以下のようなクラスがあるとします。

public class MyClass {
    private DataService dataService;

    public MyClass(DataService dataService) {
        this.dataService = dataService;
    }

    public List getNames() {
        return dataService.getNames();
    }
}

ここで、MyClassはDataServiceに依存しており、getNamesメソッドを実行する際には、DataServiceが必要となります。

・Mockitoをクラスパスに追加します。

次に、テストメソッド内で以下のようにモックオブジェクトを作成します。

@Test
public void testGetNames() {
    DataService dataService = Mockito.mock(DataService.class);
    MyClass myClass = new MyClass(dataService);
    
    List expected = Arrays.asList("foo", "bar", "baz");
    Mockito.when(dataService.getNames()).thenReturn(expected);
    
    List actual = myClass.getNames();
    assertEquals(expected, actual);
}


ここでは、Mockito.mockメソッドを使用してDataServiceのモックオブジェクトを作成しています。

次に、Mockito.whenメソッドを使用して、dataService.getNames()が呼び出された場合に返す値を指定しています。

最後に、テスト対象のメソッドを呼び出して、期待される結果と一致するかどうかをアサーションで検証しています。


5. まとめ


以上のように、JUnitはJavaプログラミングにおいて、ユニットテストを行うために非常に便利だということがわかりました。

テストメソッド内では、アサーションを使用して期待される結果と実際の結果が一致するかを検証し、テストの合格不合格を判断します。

Junitでは、assertEqualsやassertTrueなどの代表的なアサーションが提供されています。


また、テストメソッド内でモックを使用することで、外部のクラスやオブジェクトの振る舞いをシミュレートすることができます。

Junitでは、モックライブラリや自分でモックオブジェクトを実装することで、簡単にモックを利用することができます。

さらに、テストメソッドの前後に実行されるライフサイクルメソッドである@Beforeや@Afterを使うことで、テストメソッドの実行前後に特定の処理を実行することもできます。


JUnitを使うことで、テスト駆動開発(TDD)やリファクタリングなどの開発手法を効果的に実践することができそうです。

今回も、ありがとうございました。