Spring Boot 2.7を利用したJavaアプリケーションでJUnitを用いると、通常はJUnit5で動作するが、JUnit4とJUnit5の両方で動作するような設定も行うことができる。
今回は、Spring Boot 2.7を利用したJavaアプリケーションのJUnitによるテストコードを、JUnit4とJUnit5の両方で動作できるようにし、更にMockitoを利用してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
前提条件の記事のプログラムを、ビルドツールmavenを利用しSTS上に配置後、JUnitを用いたテストコードを作成する。
作成したサンプルプログラムの構成は、以下の通り。なお、下記の赤枠は、前提条件のプログラムから変更したプログラムである。

pom.xmlの内容は以下の通りで、spring-boot-starter-testを使う設定を、JUnit4, JUnit5の両方で使えるよう、変更している。
<?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.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.demo</groupId>
<artifactId>demoSpringTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demoSpringTest</name>
<description>Demo Web Project for Spring Boot on Azure</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- バリデーションチェックを行うための設定 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- lombokを利用するための設定 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- SQL Serverを利用するための設定 -->
<!-- ドライバーが SSL (Secure Sockets Layer) 暗号化による
SQL Server への安全な接続を確立できませんでした。というエラー
(SQLServerException)を回避するため、SQL Serverに
接続するためのJDBCドライバのバージョンを変更 -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.1.jre8</version>
</dependency>
<!-- MyBatisを利用するための設定 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.2</version>
</dependency>
<!-- テスト用の設定 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 -->
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</exclusion>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JUnit5を利用するための設定 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit5でMockitoを利用するための設定 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit4を利用するための設定(Mockitoも使える) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- テスト用の設定 end -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>また、JUnit4でMockitoを利用した際のソースコードは、以下の通り。
package com.example.demo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.time.LocalDate;
import java.util.List;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.any;
// JUnit4のアサーションを指定
import static org.junit.Assert.assertEquals;
@RunWith(JUnit4.class) // JUnit4で実行
public class DemoServiceImplTestJunit4 {
/**
* テスト対象のクラス
* (今回はSpring Bootを利用しないため、Serviceではなく
* ServiceImplを対象クラスに指定している)
*/
@InjectMocks
private DemoServiceImpl demoServiceImpl;
/**
* テスト対象のクラス内で呼ばれるクラスのMockオブジェクト
*/
@Mock
private UserDataMapper mapper;
/**
* 初期化したMockオブジェクトを保持するクラス
*/
private AutoCloseable closeable;
/**
* 前処理(各テストケースを実行する前に行われる処理)
*/
@Before // JUnit4のアノテーション
public void init() {
/* @Mockアノテーションのモックオブジェクトを初期化
* これを実行しないと@Mockアノテーション、@InjectMocksを付与した
* Mockオブジェクトが利用できない
* MockitoAnnotations.initMocksメソッドは非推奨となったため
* 代わりにopenMocksメソッドを利用 */
closeable = MockitoAnnotations.openMocks(this);
// Mockの設定
// mapper.findMaxId()メソッドを実行した際の戻り値をここで設定
when(mapper.findMaxId()).thenReturn(2L);
}
/**
* DemoServiceImplクラスのcreateOrUpdateForAddメソッド(追加時)の確認
*/
@Test // JUnit4のアノテーション
public void testCreateOrUpdateForAdd(){
// 追加処理を行う場合の、テスト対象メソッドの引数を生成
DemoForm demoFormAdd = makeDemoForm(null, "テスト プリン3"
, LocalDate.of(2014, 4, 20), SexEnum.MAN);
// テスト対象メソッドの実行
demoServiceImpl.createOrUpdate(demoFormAdd);
System.out.println("*** demoServiceImpl.createOrUpdateForAdd"
+ "(DemoForm(追加用))の実行結果 ***");
// テスト対象メソッドを実行した結果、mapper.findMaxId()が1回呼ばれたことを確認
verify(mapper, times(1)).findMaxId();
System.out.println("mapper.findMaxId()は1回呼ばれました");
// テスト対象メソッドを実行した結果、mapper.create(UserData)が1回呼ばれたことを確認
ArgumentCaptor<UserData> userDataCaptor
= ArgumentCaptor.forClass(UserData.class);
verify(mapper, times(1))
.create(userDataCaptor.capture());
System.out.println("mapper.create(UserData)は1回呼ばれました");
// mapper.create(UserData)を呼び出した際の引数が想定通りであることを確認
List<UserData> listUserData = userDataCaptor.getAllValues();
assertEquals(1, listUserData.size());
UserData expectUserData = makeUserData(3L, "テスト プリン3"
, LocalDate.of(2014, 4, 20), SexEnum.MAN);
assertEquals(expectUserData.toString(), listUserData.get(0).toString());
System.out.println("mapper.create(UserData)の引数 : "
+ listUserData.get(0).toString());
// テスト対象メソッドを実行した結果、mapper.update(UserData)は呼ばれないことを確認
// any()は任意の引数を表す
verify(mapper, times(0)).update(any());
System.out.println("mapper.update(UserData)は呼ばれませんでした");
System.out.println();
}
/**
* DemoServiceImplクラスのcreateOrUpdateForAddメソッド(更新時)の確認
*/
@Test // JUnit4のアノテーション
public void testCreateOrUpdateForUpdate(){
// 更新処理を行う場合の、テスト対象メソッドの引数を生成
DemoForm demoFormUpd = makeDemoForm(2L, "テスト プリン2"
, LocalDate.of(2013, 3, 19), SexEnum.WOMAN);
// テスト対象メソッドの実行
demoServiceImpl.createOrUpdate(demoFormUpd);
System.out.println("*** demoServiceImpl.createOrUpdateForAdd"
+ "(DemoForm(更新用))の実行結果 ***");
// テスト対象メソッドを実行した結果、mapper.findMaxId()が呼ばれないことを確認
verify(mapper, times(0)).findMaxId();
System.out.println("mapper.findMaxId()は呼ばれませんでした");
// テスト対象メソッドを実行した結果、mapper.create(UserData)が呼ばれないことを確認
verify(mapper, times(0)).create(any());
System.out.println("mapper.create(UserData)は呼ばれませんでした");
// テスト対象メソッドを実行した結果、mapper.update(UserData)が1回呼ばれたことを確認
ArgumentCaptor<UserData> userDataCaptor
= ArgumentCaptor.forClass(UserData.class);
verify(mapper, times(1))
.update(userDataCaptor.capture());
System.out.println("mapper.update(UserData)は1回呼ばれました");
// mapper.update(UserData)を呼び出した際の引数が想定通りであることを確認
List<UserData> listUserData = userDataCaptor.getAllValues();
assertEquals(1, listUserData.size());
UserData expectUserData = makeUserData(2L, "テスト プリン2"
, LocalDate.of(2013, 3, 19), SexEnum.WOMAN);
assertEquals(expectUserData.toString(), listUserData.get(0).toString());
System.out.println("mapper.update(UserData)の引数 : "
+ listUserData.get(0).toString());
System.out.println();
}
/**
* 後処理(各テストケースを実行した前に行われる処理)
* @throws Exception 何らかの例外
*/
@After // JUnit4のアノテーション
public void terminate() throws Exception {
// Mockオブジェクトのリソースを解放
closeable.close();
}
/**
* ユーザーデータを生成する
* @param id ID
* @param name 名前
* @param birthDay 生年月日
* @param sexEnum 性別Enum
* @return ユーザーデータ
*/
private UserData makeUserData(Long id, String name, LocalDate birthDay, SexEnum sexEnum){
UserData userData = new UserData();
if(id != null){
userData.setId(id);
}
userData.setName(name);
if(birthDay != null){
userData.setBirthY(birthDay.getYear());
userData.setBirthM(birthDay.getMonthValue());
userData.setBirthD(birthDay.getDayOfMonth());
}
if(sexEnum != null){
userData.setSex(sexEnum.getSex());
userData.setSex_value(sexEnum.getSex_value());
}
return userData;
}
/**
* Demoフォームオブジェクトを生成する
* @param id ID
* @param name 名前
* @param birthDay 生年月日
* @param sexEnum 性別Enum
* @return Demoフォームオブジェクト
*/
private DemoForm makeDemoForm(Long id, String name, LocalDate birthDay, SexEnum sexEnum){
DemoForm demoForm = new DemoForm();
if(id != null){
demoForm.setId(String.valueOf(id));
}
demoForm.setName(name);
if(birthDay != null){
demoForm.setBirthYear(String.valueOf(birthDay.getYear()));
demoForm.setBirthMonth(String.valueOf(birthDay.getMonthValue()));
demoForm.setBirthDay(String.valueOf(birthDay.getDayOfMonth()));
}
if(sexEnum != null){
demoForm.setSex(sexEnum.getSex());
demoForm.setSex_value(sexEnum.getSex_value());
}
return demoForm;
}
}さらに、JUnit5でMockitoを利用した際のソースコードは、以下の通り。
package com.example.demo;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
import java.time.LocalDate;
import java.util.List;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.any;
// JUnit5のアサーションを指定
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(MockitoExtension.class) // JUnit5で実行
public class DemoServiceImplTestJunit5 {
/**
* テスト対象のクラス
* (今回はSpring Bootを利用しないため、Serviceではなく
* ServiceImplを対象クラスに指定している)
*/
@InjectMocks
private DemoServiceImpl demoServiceImpl;
/**
* テスト対象のクラス内で呼ばれるクラスのMockオブジェクト
*/
/* JUnit5でorg.mockito.exceptions.misusing.UnnecessaryStubbingException
* 例外が発生するのを抑止するため、@Mockアノテーションの属性にlenient=true を指定 */
@Mock(lenient = true)
private UserDataMapper mapper;
/**
* 初期化したMockオブジェクトを保持するクラス
*/
private AutoCloseable closeable;
/**
* 前処理(各テストケースを実行する前に行われる処理)
*/
@BeforeEach // JUnit5のアノテーション
public void init() {
/* @Mockアノテーションのモックオブジェクトを初期化
* これを実行しないと@Mockアノテーション、@InjectMocksを付与した
* Mockオブジェクトが利用できない
* MockitoAnnotations.initMocksメソッドは非推奨となったため
* 代わりにopenMocksメソッドを利用 */
closeable = MockitoAnnotations.openMocks(this);
// Mockの設定
// mapper.findMaxId()メソッドを実行した際の戻り値をここで設定
when(mapper.findMaxId()).thenReturn(2L);
}
/**
* DemoServiceImplクラスのcreateOrUpdateForAddメソッド(追加時)の確認
*/
@Test // JUnit5のアノテーション
public void testCreateOrUpdateForAdd(){
// 追加処理を行う場合の、テスト対象メソッドの引数を生成
DemoForm demoFormAdd = makeDemoForm(null, "テスト プリン3"
, LocalDate.of(2014, 4, 20), SexEnum.MAN);
// テスト対象メソッドの実行
demoServiceImpl.createOrUpdate(demoFormAdd);
System.out.println("*** demoServiceImpl.createOrUpdateForAdd"
+ "(DemoForm(追加用))の実行結果 ***");
// テスト対象メソッドを実行した結果、mapper.findMaxId()が1回呼ばれたことを確認
verify(mapper, times(1)).findMaxId();
System.out.println("mapper.findMaxId()は1回呼ばれました");
// テスト対象メソッドを実行した結果、mapper.create(UserData)が1回呼ばれたことを確認
ArgumentCaptor<UserData> userDataCaptor
= ArgumentCaptor.forClass(UserData.class);
verify(mapper, times(1))
.create(userDataCaptor.capture());
System.out.println("mapper.create(UserData)は1回呼ばれました");
// mapper.create(UserData)を呼び出した際の引数が想定通りであることを確認
List<UserData> listUserData = userDataCaptor.getAllValues();
assertEquals(1, listUserData.size());
UserData expectUserData = makeUserData(3L, "テスト プリン3"
, LocalDate.of(2014, 4, 20), SexEnum.MAN);
assertEquals(expectUserData.toString(), listUserData.get(0).toString());
System.out.println("mapper.create(UserData)の引数 : "
+ listUserData.get(0).toString());
// テスト対象メソッドを実行した結果、mapper.update(UserData)は呼ばれないことを確認
// any()は任意の引数を表す
verify(mapper, times(0)).update(any());
System.out.println("mapper.update(UserData)は呼ばれませんでした");
System.out.println();
}
/**
* DemoServiceImplクラスのcreateOrUpdateForAddメソッド(更新時)の確認
*/
@Test // JUnit5のアノテーション
public void testCreateOrUpdateForUpdate(){
// 更新処理を行う場合の、テスト対象メソッドの引数を生成
DemoForm demoFormUpd = makeDemoForm(2L, "テスト プリン2"
, LocalDate.of(2013, 3, 19), SexEnum.WOMAN);
// テスト対象メソッドの実行
demoServiceImpl.createOrUpdate(demoFormUpd);
System.out.println("*** demoServiceImpl.createOrUpdateForAdd"
+ "(DemoForm(更新用))の実行結果 ***");
// テスト対象メソッドを実行した結果、mapper.findMaxId()が呼ばれないことを確認
verify(mapper, times(0)).findMaxId();
System.out.println("mapper.findMaxId()は呼ばれませんでした");
// テスト対象メソッドを実行した結果、mapper.create(UserData)が呼ばれないことを確認
verify(mapper, times(0)).create(any());
System.out.println("mapper.create(UserData)は呼ばれませんでした");
// テスト対象メソッドを実行した結果、mapper.update(UserData)が1回呼ばれたことを確認
ArgumentCaptor<UserData> userDataCaptor
= ArgumentCaptor.forClass(UserData.class);
verify(mapper, times(1))
.update(userDataCaptor.capture());
System.out.println("mapper.update(UserData)は1回呼ばれました");
// mapper.update(UserData)を呼び出した際の引数が想定通りであることを確認
List<UserData> listUserData = userDataCaptor.getAllValues();
assertEquals(1, listUserData.size());
UserData expectUserData = makeUserData(2L, "テスト プリン2"
, LocalDate.of(2013, 3, 19), SexEnum.WOMAN);
assertEquals(expectUserData.toString(), listUserData.get(0).toString());
System.out.println("mapper.update(UserData)の引数 : "
+ listUserData.get(0).toString());
System.out.println();
}
/**
* 後処理(各テストケースを実行した前に行われる処理)
* @throws Exception 何らかの例外
*/
@AfterEach // JUnit5のアノテーション
public void terminate() throws Exception {
// Mockオブジェクトのリソースを解放
closeable.close();
}
/**
* ユーザーデータを生成する
* @param id ID
* @param name 名前
* @param birthDay 生年月日
* @param sexEnum 性別Enum
* @return ユーザーデータ
*/
private UserData makeUserData(Long id, String name, LocalDate birthDay, SexEnum sexEnum){
UserData userData = new UserData();
if(id != null){
userData.setId(id);
}
userData.setName(name);
if(birthDay != null){
userData.setBirthY(birthDay.getYear());
userData.setBirthM(birthDay.getMonthValue());
userData.setBirthD(birthDay.getDayOfMonth());
}
if(sexEnum != null){
userData.setSex(sexEnum.getSex());
userData.setSex_value(sexEnum.getSex_value());
}
return userData;
}
/**
* Demoフォームオブジェクトを生成する
* @param id ID
* @param name 名前
* @param birthDay 生年月日
* @param sexEnum 性別Enum
* @return Demoフォームオブジェクト
*/
private DemoForm makeDemoForm(Long id, String name, LocalDate birthDay, SexEnum sexEnum){
DemoForm demoForm = new DemoForm();
if(id != null){
demoForm.setId(String.valueOf(id));
}
demoForm.setName(name);
if(birthDay != null){
demoForm.setBirthYear(String.valueOf(birthDay.getYear()));
demoForm.setBirthMonth(String.valueOf(birthDay.getMonthValue()));
demoForm.setBirthDay(String.valueOf(birthDay.getDayOfMonth()));
}
if(sexEnum != null){
demoForm.setSex(sexEnum.getSex());
demoForm.setSex_value(sexEnum.getSex_value());
}
return demoForm;
}
}その他のソースコードについては、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-27-junit4-junit5/demoSpringTest/
サンプルプログラムの実行結果
サンプルプログラムの実行結果は、以下の通り。
1)「DemoServiceImplTestJunit4.java」を実行した結果は、以下の通りで、正常に実行できている。

2)「DemoServiceImplTestJunit5.java」を実行した結果は、以下の通りで、正常に実行できている。

サンプルプログラムのpom.xml(テスト用の設定)の完成経緯
サンプルプログラムのpom.xml(テスト用の設定)が完成するまでの経緯は、以下の通り。
1) pom.xmlの「テスト用の設定」を、以下のように修正する。
<!-- テスト用の設定 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- テスト用の設定 end -->2) Spring Boot 2.7の場合、デフォルトでJUnit5を利用する設定になっているため、以下のように、JUnit4のテストクラスでコンパイルエラーが発生していることが確認できる。

3) pom.xmlの「テスト用の設定」を、以下のように修正する。
<!-- テスト用の設定 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit4を利用するための設定(Mockitoも使える) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- テスト用の設定 end -->4) 以下のように、JUnit4のテストクラスのコンパイルエラーが解消されたことが確認できる。

5) ただし、実行すると、以下のように「テスト・ランナー ‘Junit 5’のテストが見つかりません。」と表示される。


6) pom.xmlの「テスト用の設定」を、以下のように修正する。
<!-- テスト用の設定 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 -->
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</exclusion>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JUnit4を利用するための設定(Mockitoも使える) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- テスト用の設定 end -->7) 以下のように、次はJUnit5のテストクラスでコンパイルエラーが発生することが確認できる。

8) pom.xmlの「テスト用の設定」を、以下のように修正する。
<!-- テスト用の設定 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 -->
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</exclusion>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JUnit5を利用するための設定 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit4を利用するための設定(Mockitoも使える) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- テスト用の設定 end -->9) 以下のように、JUnit5のテストクラスでコンパイルエラーがまだ少し残っていることが確認できる。

10) pom.xmlの「テスト用の設定」を、以下のように、サンプルプログラムと同じ状態に修正する。
<!-- テスト用の設定 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 -->
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</exclusion>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JUnit5を利用するための設定 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit5でMockitoを利用するための設定 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit4を利用するための設定(Mockitoも使える) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- テスト用の設定 end -->11) 以下のように、JUnit5のテストクラスのコンパイルエラーが無くなることが確認できる。

このときの実行結果は、「サンプルプログラムの実行結果」に記載の通りとなる。
要点まとめ
- Spring Boot 2.7を利用したJavaアプリケーションでJUnitを用いると、通常はJUnit5で動作するが、設定次第で、JUnit4とJUnit5の両方で動作した上で、Mockitoも利用できる。





