STSでJUnit5を動かす

## 概要
STSでJUnit5を使ってみます。
主に自分用備忘録。

JUnit5とは、Javaテスト用フレームワークJUnitの最新バージョンです。
STSについては後述で紹介記事へリンクを貼ります。

開発環境は次の通りです。
OS : Windows 7 Home Edition 64bit
Java : JavaSE 15
STS : 4.10.0

## STSのセットアップ
[こちら](https://spring.io/tools)からダウンロード、4.10.0 - WINDOWS 64-BITを使用しました。
4.10.0はjar形式で提供されていて、
解凍はダブルクリックで、sts-4.10.0-RELEASEフォルダが作成されます。
その後のセットアップは[自分の備忘録](https://qiita.com/harayoshi/items/fca60e68087640b26292)を参考にしました。
「STSって何？」という方もよろしければご覧ください。

この記事ではSTSのフォルダをc:\sts-4.10.0にしています。

## プロジェクトの作成
STSを起動して、下記のCreate new Spring Starter Projectをクリックします。
![1.CreateNewSpringProject.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/b26e1a52-2cb9-acdc-4e5b-fc79cd2acf69.png)

プロジェクトの設定をします。
デフォルト（初期値）から変更した箇所はJava Versionのみです。
![2.SetNewSpringStarterProject.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/e4a0a203-a54c-6a61-4c40-701fb0f3ce52.png)

Spring Bootのライブラリ参照を設定します。
デフォルトからSpring Bootのバージョンを2.4.4にしています。
![2.5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/44b721b4-bdb6-7984-3bda-09a768d6b1ce.png)

**注意点：JUnit5をこの段階でライブラリ参照設定できません。**

site infoを設定、変更無しです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/c1e6a25a-7911-7db8-7688-224628349c2c.png)

プロジェクトができました。
!![3.NewProject.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/ea8666a9-21fd-ef40-8422-6307fa6098ec.png)

## Unit5を参照する方法
まず、参照するライブラリとして追加します。参考記事は[こちら](https://qiita.com/opengl-8080/items/efe54204e25f615e322f#%E5%BF%85%E8%A6%81%E3%81%AA%E3%82%A2%E3%83%BC%E3%83%86%E3%82%A3%E3%83%95%E3%82%A1%E3%82%AF%E3%83%88)。
[Maven Repository](https://mvnrepository.com/)を検索して、2021/4/11時点で[最新バージョン5.7.1](https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter/5.7.1)を
pom.xmlに以下を追記します。

```pom.xml(JUnit5のみ)
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.1</version>
    <scope>test</scope>
</dependency>
```

追記する箇所ですが、pom.xmlの```<dependencies>```タグ内です。
pom.xmlはSTSでプロジェクト作成した際に自動生成されています。
追記するとこうなります。

```pom.xml(参照を追記した後)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>15</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!-- ここから追記 -->
		<!--  https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
		<dependency>
		    <groupId>org.junit.jupiter</groupId>
		    <artifactId>junit-jupiter</artifactId>
		    <version>5.7.1</version>
		    <scope>test</scope>
		</dependency>
		<!-- ここまで追記 -->

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```

参照ライブラリをダウンロードします。
プロジェクトルートを選択、右クリック->Maven->Update projectをクリック
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/18b42e2f-2631-6097-a3f5-d70229338d97.png)

OKボタンをクリック、アップデートを開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/eb1770c6-ba6c-02a9-7143-820b4aa8977a.png)

JUnit5参照ができましたが、参照しているJREがJavaSE-15になっているため、修正します。
2021/4/11時点ではSTSにJavaSE 16がバンドル(同梱)されていないためです。

## STSにバンドルされていないJREを指定する方法
**※下記の方法はSTSのworkspaceのJREを指定する方法です。**
手順をご存知の方は読み飛ばして、[次の段落](https://qiita.com/harayoshi/private/a06123af6d06160c9171#%E8%A9%B0%E3%81%BE%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E7%AE%87%E6%89%80)からご覧ください。

JRE System Libraryを右クリック->Build Path->Configure Build Path...を選択します。
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/aa465a9f-acd8-6c28-6a67-75c1e8d4098b.png)

JRE System Libraryをクリック、Editボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/80c3f945-3545-b70e-ecab-509da6cdbaff.png)

Installed JREsボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/f6056282-30e6-0f72-8830-18f7bcaa0e90.png)

Addボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/1bdc2215-d3b3-81a4-f960-c336c0612640.png)

Standard VMをクリック、Nextボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/96054089-543a-8fff-a307-a718cdd77b7d.png)

JRE home:のDirectoryボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/80f52ea7-d0c3-140b-bbea-2ac44ac1e6da.png)

JavaSE 16のインストールディレクトリ
(デフォルトだとC:\Program Files\Java\jdk-16)を選択します。
ライブラリが表示されたら、Finishボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/c13296dd-f647-a2d8-4017-06adca7676ed.png)

jdkの方をチェックして、Apply and Closeボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/d1796359-97cf-5ef7-1903-2af99b4f8b80.png)

ラジオボタンでAlternative JREを選択、
ドロップダウンからjdk-16を選択、
Finishボタンをクリックします。
参照するJREを変更できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/3e9f0085-4864-d0d5-d67b-0e843ac5fd5b.png)

## 詰まっている箇所
JRE参照ライブラリを切り替えてからMavenのUpdate Projectを実行したところ、
JavaSE 15にリセットされました。
色々調べた結果、[spring-boot-maven-pluginの本家](https://spring.pleiades.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/#build-info)を確認しましたが、
記事初版投稿時点(2021/4/11)ではJavaSE 15で試しています。
他にもmaven-compiler-plugin関連ではありますが、
[こちら](https://qiita.com/kz1202/items/aa0f2f110908ff7ff530)とか、[こちら](https://qiita.com/taumax/items/0507123ead3faa2d750a)も拝見しました。

## Lombokをインストールする
ボイラープレートを書かないようにするため、
[Lombok本家セットアップ手順](https://projectlombok.org/setup/eclipse)を見ながら、
Lombokをインストールします。

## テスト対象を作る
テスト対象はシンプルで確実な答えがあるものにしたかったので、
フィボナッチ数を指定した数だけ計算、配列として保持するクラスを用意しました。

```FibonacciNumberCreator.java
package com.example.demo;

import lombok.Data;

/**
 * フィボナッチ数を作成するクラス
 * 
 * @author harayoshi
 */
@Data
public class FibonacciNumberCreator {

	private final int[] atFirstArray = {0, 1};
	private final String messateTemplate = "F%s = %s\r\n";

	/** フィボナッチ数のリスト */
	private int[] fibonacciNumbers;

	/**
	 * コンストラクタ(フィボナッチ数のリスト作成)
	 * 
	 * @param size
	 */
	public FibonacciNumberCreator(int size) {

		// サイズが負の数の場合、リストの最小デフォルト値を設定
		if (size < 0) {
			size = atFirstArray.length;
		}

		// 1,2番目をリストに格納
		fibonacciNumbers = new int[size];
		for (int i = 0; i < atFirstArray.length; i++) {
			fibonacciNumbers[i] = atFirstArray[i];
		}
		
		// 3番目以降を計算、リストに格納
		for (int i = 2; i < size; i++) {
			int next = fibonacciNumbers[i - 2] + fibonacciNumbers[i - 1];
			fibonacciNumbers[i] = next;
		}
	}

	/**
	 * インスタンスが持つリストをテンプレートを使って文字列化
	 */
	@Override
	public String toString() {
		String message = "";
		// 要素ごとにメッセージを追記
		for (int i = 0; i < this.getFibonacciNumbers().length; i++) {
			message += String.format(messateTemplate, String.valueOf(i), String.valueOf(this.getFibonacciNumbers()[i]));
		}
		return message;
	}

}
```

このクラスに対してJUnit5のテストケースを作成します。
テスト対象クラスを右クリック->New->JUnit Test Case
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/7d14b625-7896-7ef1-a9c3-4fb536b79e60.png)

Which method stubs would you like to create?は全てチェック有りにして、
Nextボタンをクリックします。
ちなみに、JUnitのバージョンはデフォルトで選択状態でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/3047f7d9-54d9-7443-047c-1f4680a167a4.png)

テスト対象メソッドを選択して、Finishボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/68403591-bc70-0484-c4ac-ddf09ee77f94.png)

クラスが作成されました。

```FibonacciNumberCreatorTest.java
package com.example.demo;

import static org.junit.jupiter.api.Assertions.*;

import java.util.Arrays;
import java.util.List;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class FibonacciNumberCreatorTest {

	private FibonacciNumberCreator creator;
	
	@BeforeAll
	static void setUpBeforeClass() throws Exception {
	}

	@AfterAll
	static void tearDownAfterClass() throws Exception {
	}

	@BeforeEach
	void setUp() throws Exception {
	}

	@AfterEach
	void tearDown() throws Exception {
	}

	@Test
	void testToString() {
		fail("Not yet implemented");
	}

}
```

クラスを作成する前に正解となるフィボナッチ数列を[こちら](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0#%E6%A6%82%E8%A6%81)確認しました。

クラスは次の通りに書き換えました。

```FibonacciNumberCreatorTest.java
package com.example.demo;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class FibonacciNumberCreatorTest {

	private FibonacciNumberCreator creator;
	
	@BeforeAll
	static void setUpBeforeClass() throws Exception {
		// no implements
	}

	@AfterAll
	static void tearDownAfterClass() throws Exception {
		// no implements
	}

	@BeforeEach
	void setUp() throws Exception {
		// no implements
	}

	@AfterEach
	void tearDown() throws Exception {
		creator = null;
	}

	@Test
	void testToString() {
		int size = 4;
		creator = new FibonacciNumberCreator(size);
		int[] expected = {0, 1, 1, 2};
		int[] actual = creator.getFibonacciNumbers();
		Assertions.assertArrayEquals(expected, actual);
	}

}
```

テスト実行時はテストクラスを右クリック->Run As->JUnit Testをクリックします。
![6.5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/5133e3a7-ca14-e79d-94c1-48f92323645c.png)

テスト元クラスを確認するダイアログが表示されますが、
そのままOKボタンをクリックします。

テストできました。
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/240058f6-04c9-2b30-cce3-f53700b92761.png)


## 結論
簡単なプログラム、テストのみでの確認ですが、今回分かったのは
**STSは「JUnitのバージョンに合わせて、JUnit5でもこれまでと同じ手順でテスト実行できる」**
ということです。

最後まで読んでいただき、ありがとうございました。