【個人用】JUnit5備忘録メモ(作業中)

JUnit5でよく使う処理などをよく忘れるので備忘録として記載する。

標準機能でできること。できないので自作が必要な場合をメモする。

# 0.テストの定義

## 0-1.ユニットテスト
関数やクラスなど、コードの一部をチェックするテスト。
単体テスト。
ユニットテストはシステムの他の部分から切り離された状態で行われる。

## 0-2.統合テスト
複数のクラスやサブシステムなど、一回り大きなコードをチェックするテスト。
ユニットテストとシステムテストの間に位置する。

## 0-3.システムテスト
システム全体をチェックするテスト。
エンドツーエンドテスト。

## 0-4.機能テスト
システムのただ１つの機能をテストする。

## 0-5.皮下テスト(subcutaneous test)
最終的なエンドユーザーインタフェースに対して実行されるのではなく、表面のすぐ下にあるインタフェースに対して実行されるテスト。


# 1.やりたいこと

## 1-1.事前準備
+ データのコピー


## 1-2.テスト検証
+ bool値の比較
+ Stringの比較
+ Stringの部分比較
+ ファイルの存在チェック
+ ファイルの内容チェック
+ 例外の内容確認


## 1-3.事後処理
+ データの削除


## 1-4.その他

# 2.基礎知識

## 2-1.基礎知識
+ JUnit5（Jupiter）では、テスト失敗時のエラーメッセージは最後の引数に書く。


## 2-2.インストール
基本的なインストールは[Javaの開発環境メモ](https://qiita.com/kero3/items/2a22c786b89aa7e8dcf8#4-2junit)を参照。

最低限必要な内容としては以下。

```xml:pom.xml
        
	<dependencies>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter</artifactId>
			<version>5.6.2</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.1</version>
				<configuration>
					<workingDirectory>${project.basedir}/work</workingDirectory>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<release>8</release>
				</configuration>
			</plugin>

		</plugins>
	</build>
```

### 2-2-1.アサーションライブラリ

Hamcrest,AssertJなどがあるが、AssertJを使用する。

```xml:pom.xml
		<dependency>
			<groupId>org.assertj</groupId>
			<artifactId>assertj-core</artifactId>
			<version>3.17.2</version>
			<scope>test</scope>
		</dependency>

```

## 2-3.文字列の比較

```java
    assertThat("HOKKAIDO").as("文字列のテストで失敗")
      .isEqualTo("HOKKAIDO")
      .startsWith("HO")
      .endsWith("DO")
      .contains("KK")
      .isEqualToIgnoringCase("hokkaido")
      .matches("[A-Z]{8}");
```

## 2-4.アノテーション

@BeforeAll をつけたメソッドは、テストクラス内で一番最初に一度だけ実行される
メソッドが static である必要がある
@BeforeEach をつけたメソッドは、各テストメソッドの前に実行される
@AfterAll をつけたメソッドは、テストクラス内で一番最後に一度だけ実行される
メソッドが static である必要がある
@AfterEach をつけたメソッドは、各テストメソッドの後に実行される

## 2-9.参考URL
https://qiita.com/disc99/items/31fa7abb724f63602dc9

# 3.TIPS

## 3-1.ファイルロック
対象ファイルをロックし、読み取りできないようにする。

```java

    try (
        FileChannel fc =
            FileChannel.open(Paths.get(""), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
        FileLock lock = fc.tryLock()) {
      // ロック取得後の操作
    } catch (Exception e) {
      // ロック取得失敗
    }
```
## 3-2.ファイルの比較

ファイルサイズが小さければcommons-ioを使って以下の用にする。

```java
    assertThat(FileUtils.readFileToString(file1, "UTF-8"),
        is(FileUtils.readFileToString(file2, "UTF-8")));
```


## 3-3.VM引数を指定

## 3-4.テストの実行順を指定

```java
package sample;

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

import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

@TestMethodOrder(OrderAnnotation.class)
public class SampleTest {

	@Test
	@Order(3)
	void test1111() {
		System.out.println("1");
		assertTrue(true);
	}


	@Test
	@Order(2)
	 void test555() {
		System.out.println("2");
		assertTrue(true);
	}

	@Test
	@Order(1)
	 void test3() {
		System.out.println("3");
		assertTrue(true);
	}
}
```

参考サイト：https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-execution-order

各メソッドに@Orderアノテーションを指定すると、小さい値からテストが実施される。
常軌の例では、3,2,1の順で出力される

# 4.testフォルダ
Unitテストはテスト対象のクラスと同じパッケージ名とし、クラス名+Testとする。



# 5.テストベースクラス仕様
作業フォルダに必要なファイルと入力ファイルを毎回コピーする。
指定したサブフォルダと同階層にある入力データをコピーし、そのあとにサブフォルダ内の入力データをコピーする。

## 5-1.作業フォルダ
作業フォルダは「src/test/WORK」とする。
「src/test/resources」の下にはせず、resourcesと同階層とする。

## 5-2.テストデータフォルダ
テストフォルダは「src/test/resources/テストデータ」とする。

## 5-3.フォルダ構成

テスト用のフォルダ、「テストデータフォルダ」の下に以下の構成とする。
テストクラスは親フォルダを、テストメソッドにはサブフォルダを指定する。
それ以外は以下の2つのフォルダを作成する。
functional：統合テスト、機能テスト
system：システムテスト、皮下テスト
上記2つのフォルダ以下には日本語のパッケージ名とクラスとする。

+親フォルダ
　├サブフォルダ１
　│├入力データ
　│└想定結果フォルダ
　│
　├サブフォルダ２
　│├入力データ
　│└想定結果フォルダ
　│
　└入力データ

# 6. Mockito