Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その15 )( JUnit 4 を依存関係から削除する+他3点の気づいた点を変更する )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- Spring Boot を 2.5系にバージョンアップしても JUnit 4 が依存関係に残ることに気づいたので除去します。
- IntelliJ IDEA で Rebuild Project した時に生成される out ディレクトリが Gradle の clean タスクを実行しても残ることに気づいたので削除されるようにします。
- Mockito.mockStatic を使用するテストでは try-with-resources 構文を使用してリソースが close されるようにしないといけないことに気づいたので修正します。
- JDK 17 がサポートされた Lombok 1.18.22 がリリースされていたのでバージョンアップします。
参照したサイト・書籍
How to exclude Gradle dependencies
https://tomgregory.com/how-to-exclude-gradle-dependencies/@StandardException annotation for generating exception constructors
https://github.com/projectlombok/lombok/pull/2702
目次
- 依存関係から JUnit 4 を除去する
- JUnit 4 のモジュールを利用しているクラスを変更・削除する
- src/test/java/ksbysample/common/test/extension/db/TestDataExtension.java
- src/test/java/ksbysample/common/test/extension/mail/MailServerExtension.java
- src/test/java/ksbysample/common/test/extension/mockmvc/SecurityMockMvcExtension.java
- src/test/java/ksbysample/common/test/helper/DescriptionWrapper.java
- src/test/groovy/ksbysample/webapp/lending/SampleHelperTest.groovy
- clean タスクで out ディレクトリが削除されるようにする
- Mockito.mockStatic を呼び出しているテストで try-with-resources 構文を使用してリソースが close されるようにする
- Lombok を 1.18.20 → 1.18.22 にバージョンアップする
- WebApplicationRuntimeException クラスを Lombok の @StandardException を利用して書き直す
- build タスクでエラーが出ないことを確認する
手順
依存関係から JUnit 4 を除去する
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その100 )( Gradle を 6.9.1 → 7.2 へ、Spring Boot を 2.4.10 → 2.5.4 へ、Geb を 4.1 → 5.0 へバージョンアップする2 ) の作業で Spring Boot を 2.5系にバージョンアップしても JUnit 4 が依存関係に残っていることに気づいたので、除去することにします。
今回は個々のモジュールに exclude を記述して除外するのではなく configurations block に exclude を記述する方法を採用します。build.gradle を以下のように変更します。
configurations {
compileOnly.extendsFrom annotationProcessor
// annotationProcessor と testAnnotationProcessor、compileOnly と testCompileOnly を併記不要にする
testAnnotationProcessor.extendsFrom annotationProcessor
testImplementation.extendsFrom compileOnly
// JUnit 4 が依存関係に入らないようにする
all {
exclude group: "junit", module: "junit"
}
// for SpotBugs
spotbugsStylesheets { transitive = false }
}
all { exclude group: "junit", module: "junit" }を追加します。
JUnit 4 のモジュールを利用しているクラスを修正する
src/test/java/ksbysample/common/test/extension/db/TestDataExtension.java
@Component public class TestDataExtension implements BeforeEachCallback, AfterEachCallback { .......... @Override public void beforeEach(ExtensionContext context) { before(new ExtensionContextWrapper(context)); } @Override public void afterEach(ExtensionContext context) { after(new ExtensionContextWrapper(context)); } ..........
extends TestWatcherを削除します。- 以下のメソッドを削除します。
protected void starting(Description description) { ... }protected void finished(Description description) { ... }
src/test/java/ksbysample/common/test/extension/mail/MailServerExtension.java
@Component public class MailServerExtension implements BeforeEachCallback, AfterEachCallback { private GreenMail greenMail = new GreenMail(new ServerSetup(25, "localhost", ServerSetup.PROTOCOL_SMTP)); @Override public void beforeEach(ExtensionContext context) { greenMail.start(); } @Override public void afterEach(ExtensionContext context) { greenMail.stop(); } ..........
extends ExternalResourceを削除します。- 以下のメソッドを削除します。
protected void before() { ... }protected void after() { ... }
- beforeEach メソッド内の
before();→greenMail.start();に変更します。 - afterEach メソッド内の
after();→greenMail.stop();に変更します。
src/test/java/ksbysample/common/test/extension/mockmvc/SecurityMockMvcExtension.java
@Component @ConditionalOnWebApplication public class SecurityMockMvcExtension implements BeforeEachCallback { .......... @Override public void beforeEach(ExtensionContext context) { // 認証ユーザ用MockMvc ( user = tanaka.taro@sample.com ) UserDetails userDetailsTanakaTaro = userDetailsService.loadUserByUsername(MAILADDR_TANAKA_TARO); this.authTanakaTaro = MockMvcBuilders.webAppContextSetup(this.context) .defaultRequest(get("/").with(user(userDetailsTanakaTaro))) .apply(springSecurity()) .build(); // 認証ユーザ用MockMvc ( user = suzuki.hanako@test.co.jp ) UserDetails userDetailsSuzukiHanako = userDetailsService.loadUserByUsername(MAILADDR_SUZUKI_HANAKO); this.authSuzukiHanako = MockMvcBuilders.webAppContextSetup(this.context) .defaultRequest(get("/").with(user(userDetailsSuzukiHanako))) .apply(springSecurity()) .build(); // 認証ユーザ用MockMvc ( user = ito.aoi@test.co.jp ) UserDetails userDetailsItoAoi = userDetailsService.loadUserByUsername(MAILADDR_ITO_AOI); this.authItoAoi = MockMvcBuilders.webAppContextSetup(this.context) .defaultRequest(get("/").with(user(userDetailsItoAoi))) .apply(springSecurity()) .build(); // 非認証ユーザ用MockMvc this.noauth = MockMvcBuilders.webAppContextSetup(this.context) .apply(springSecurity()) .build(); } }
extends ExternalResourceを削除します。- before メソッド内のコードを beforeEach メソッドへ移動します。
- 以下のメソッドを削除します。
protected void before() { ... }
src/test/java/ksbysample/common/test/helper/DescriptionWrapper.java
このファイルは使用されなくなったので削除します。
src/test/groovy/ksbysample/webapp/lending/SampleHelperTest.groovy
@RunWith(Enclosed) が記述されていたので削除します。
clean タスクで out ディレクトリが削除されるようにする
build.gradle の clean block を以下のように変更します。
clean {
doLast {
rootProject.file("out").deleteDir()
rootProject.file("src/main/generated").deleteDir()
rootProject.file("src/test/generated_tests").deleteDir()
}
}
rootProject.file("out").deleteDir()を追加します。
Mockito.mockStatic を呼び出しているテストで try-with-resources 構文を使用してリソースが close されるようにする
src/test/groovy/ksbysample/webapp/lending/SampleHelperTest.groovy で以下のように書いているテストを、
@SpringBootTest
static class 異常処理のテスト {
@Autowired
private SampleHelper sampleHelper
@Test
void "SampleHelper_encryptを呼ぶとRuntimeExceptionをthrowする"() {
// setup:
Mockito.mockStatic(BrowfishUtils)
Mockito.when(BrowfishUtils.encrypt(Mockito.any()))
.thenThrow(new NoSuchPaddingException())
// expect:
assertThatThrownBy(() -> {
sampleHelper.encrypt("test")
}).isInstanceOf(RuntimeException)
}
}
try-with-resources 構文を使用してリソースが close されるよう書き直します。
@SpringBootTest
static class 異常処理のテスト {
@Autowired
private SampleHelper sampleHelper
@Test
void "SampleHelper_encryptを呼ぶとRuntimeExceptionをthrowする"() {
try (MockedStatic mockedBrowfishUtils = Mockito.mockStatic(BrowfishUtils)) {
// setup:
Mockito.when(BrowfishUtils.encrypt(Mockito.any()))
.thenThrow(new NoSuchPaddingException())
// expect:
assertThatThrownBy(() -> {
sampleHelper.encrypt("test")
}).isInstanceOf(RuntimeException)
}
}
}
Lombok を 1.18.20 → 1.18.22 にバージョンアップする
IntelliJ IDEA で build.gradle を見ていたら org.projectlombok:lombok: のところの色が変わっていて、マウスオーバーすると 1.8.22 がリリースされていることが分かりました。Alt+Enter を押すとバージョンも書き替えることも出来ます。この機能、すごい便利じゃないですか。。。

https://projectlombok.org/changelog を見ると v1.18.22 で PLATFORM: JDK17 support added. とのことなので、バージョンアップします。
build.gradle の以下の点を変更します。
dependencies {
def spockVersion = "2.0-groovy-3.0"
def jdbcDriver = "org.postgresql:postgresql:42.2.24"
def domaVersion = "2.49.0"
def lombokVersion = "1.18.22"
def errorproneVersion = "2.9.0"
..........
def lombokVersion = "1.18.20"→def lombokVersion = "1.18.22"に変更します。
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
WebApplicationRuntimeException クラスを Lombok の @StandardException を利用して書き直す
https://projectlombok.org/changelog の v1.18.22 のところを見ると @StandardException というアノテーションが追加されたとの記載があり、https://github.com/projectlombok/lombok/pull/2702 を見ると Exception クラスを継承して作成する時の基本的なコンストラクタを4つ自動生成してくれるとのこと。
便利そうなので WebApplicationRuntimeException クラスを @StandardException を利用して書き直してみます。
src/main/java/ksbysample/webapp/lending/exception/WebApplicationRuntimeException.java は現在以下のように実装していますが、
package ksbysample.webapp.lending.exception; public class WebApplicationRuntimeException extends RuntimeException { @SuppressWarnings("PMD.FieldNamingConventions") private static final long serialVersionUID = 3845674924872653036L; public WebApplicationRuntimeException() { super(); } public WebApplicationRuntimeException(String message) { super(message); } public WebApplicationRuntimeException(String message, Throwable cause) { super(message, cause); } public WebApplicationRuntimeException(Throwable cause) { super(cause); } }
@StandardException を利用して書き直すと以下のようになります。@SuppressWarnings("PMD.FieldNamingConventions") も build 時に PMD が警告を出さないことに気づいたので削除します。
package ksbysample.webapp.lending.exception; import lombok.experimental.StandardException; import java.io.Serial; @StandardException public class WebApplicationRuntimeException extends RuntimeException { @Serial private static final long serialVersionUID = 3845674924872653036L; }
build タスクでエラーが出ないことを確認する
最後に clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。

履歴
2021/10/20
初版発行。