EclipseでJUnitを動かす方法

## JUnitとは
+ Javaプログラムにおいてユニットテストができるツール（フレームワーク）を行う
+ テスト自動化ができる
    + 手作業が減るため、テスト工数削減やヒューマンエラー防止に効果あり。

## 前提条件
+ Eclipseがインストールされていること
+ 以下のような構成のプロジェクト、パッケージ、プログラムファイルを作成していること

```
ProjectA  ----  src
                 |
                 ------ xx.yy.zzz(パッケージ)
                            |
                            ------- Door.java (テスト対象クラス)
```

## 設定

パッケージxx.yy.zzz配下に、Door.java (テスト対象クラス)をテストするためのクラス「DoorTest.java」を作成します。

+ Eclipseでプロジェクトを右クリック [新規] - [その他]をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409243/693792f6-8b76-1e0e-936e-316e71d83b2f.png)

+ 「Java」 - 「JUnit」 - 「Junitテストケース」を選択して 次へ をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409243/d1f66b96-e969-af60-1969-251bc4a10100.png)

+ 下図を参考に、必要な値を設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409243/0c8abf8b-7c89-97a8-8ff2-86538d7cdcfd.png)

+ 「DoorTest.java」の雛形ができました。

```java:DoorTest.java
package xx.yy.zzz;  // テスト対象クラスと同じパッケージにする

import static org.junit.Assert.*;

import org.junit.Test;

public class DoorTest {

	@Test
	public void test() {
		fail("まだ実装されていません");
	}

}

```

+ 試しに実行してみましょう。 DoorTest.javaを右クリックして、 [実行] - [実行の構成]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409243/3934e327-fe71-6767-a9c1-0b5581301917.png)


+ 下図を参考に、必要な値を設定する。テスト・ランナーは「JUnit 4」にするのを忘れずに！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409243/051b8ff9-5649-769f-8acc-54aa0dc64bfb.png)

+ 実行結果です。failメソッドが呼び出されるので、結果は必ず「失敗」になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409243/f47f2438-bf0b-ee57-0aa3-584b52a57b63.png)

## テストプログラムを書く

### テスト対象クラス
```java:Door.java
package xx.yy.zzz;  // テストクラスと同じパッケージにする

public class Door {
	private boolean isOpen = false;

	public void open(String str) {
		if (str.equals("開けゴマ！")) {
			isOpen = true;
		} else {
                        isOpen = false;
			System.out.println("違います。");
		}
	}

	public void close() {
		isOpen = false;
	}

	// getter
	public boolean isOpen() {
		return isOpen;
	}

}
```

### テスト内容
+ test1. openメソッドで"開けゴマ！"以外を指定すると、ドアが開らない（isOpenメソッドの戻り値がfalse）こと。また、「違います。」と標準出力されていること。
+ test2. openメソッドで"開けゴマ！"を指定すると、ドアが開く（isOpenメソッドの戻り値がtrue）こと。
+ test3. closeメソッドでドアが閉じる（isOpenメソッドの戻り値がfalse）こと。

### テストクラス
```java:Door.java
package xx.yy.zzz;  // テスト対象クラスと同じパッケージにする

import static org.junit.Assert.*;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class DoorTest {

	Door door;
    private ByteArrayOutputStream baos;

	// 前処理
	@Before
	public void setUp() {
		door = new Door();

        baos = new ByteArrayOutputStream();
        System.setOut(
            new PrintStream(
                new BufferedOutputStream(baos)
            )
        );
	}


	// 「@Test」は、JUnitがテストメソッドと認識するためのアノテーション
	// public voidで作成すること
	@Test
	public void test1() {
		door.open("ドア、開いてください");

		// 標準出力
		System.out.flush();
		String expected = "違います。\r\n";
        String actual = baos.toString();

        // 期待値との確認
		assertEquals(false, door.isOpen());
        assertEquals(expected, actual);
	}

	@Test
	public void test2() {
		door.open("開けゴマ！");
		assertEquals(true, door.isOpen());
	}

	@Test
	public void test3() {
		door.close();
		assertEquals(false, door.isOpen());
	}

	// 後処理
	@After
	public void fin() {
		// DO Nothing
	}

}
```
[補足]

+ System.setOutメソッド：「標準」出力ストリームを割り当てし直します。引数はPrintStreamクラスです。
+ PrintStreamクラス：新しい出力ストリームを作成するために使います。
+ BufferedOutputStreamクラス：バッファのデータを出力ストリーム化します。
+ ByteArrayOutputStreamクラス：データがバイト配列に書き込まれる出力ストリームを実装します。