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の両方で使えるよう、変更している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | <?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を利用した際のソースコードは、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | 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を利用した際のソースコードは、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | 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の「テスト用の設定」を、以下のように修正する。
1 2 3 4 5 6 7 | <!-- テスト用の設定 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の「テスト用の設定」を、以下のように修正する。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!-- テスト用の設定 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の「テスト用の設定」を、以下のように修正する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!-- テスト用の設定 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の「テスト用の設定」を、以下のように修正する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <!-- テスト用の設定 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の「テスト用の設定」を、以下のように、サンプルプログラムと同じ状態に修正する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <!-- テスト用の設定 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も利用できる。