Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その5 )( Spock を 1.3-groovy-2.5 → 2.0-groovy-3.0 へバージョンアップする )
概要
記事一覧はこちらです。
Spring Boot 2.4.x の Web アプリを 2.5.x へバージョンアップする ( その4 )( Gradle を 6.9.1 → 7.2 へバージョンアップする ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Spock を 1.3-groovy-2.5 → 2.0-groovy-3.0 へバージョンアップします。
- Spock を 2系にバージョンアップすると JUnit 5 ベースになるので、PowerMock で作成している static method のテストを Mockito で書き直して PowerMock を依存関係から削除します。
参照したサイト・書籍
Spock - Migration Guide
https://spockframework.org/spock/docs/2.0/migration_guide.htmlGroovy Language Documentation Version 3.0.8
http://docs.groovy-lang.org/docs/groovy-3.0.8/html/documentation/Junit5 mock a static method
https://stackoverflow.com/questions/52830441/junit5-mock-a-static-method
目次
- Spock を 1.3-groovy-2.5 → 2.0-groovy-3.0 へバージョンアップする
- PowerMock で作成している static method のテストを Mockito で書き直して PowerMock を依存関係から削除する
- @Unroll アノテーションを削除する
手順
Spock を 1.3-groovy-2.5 → 2.0-groovy-3.0 へバージョンアップする
build.gradle の以下の点を変更します。
dependencyManagement { imports { // bomProperty に指定可能な property は以下の URL の BOM に記述がある // https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.5.4/spring-boot-dependencies-2.5.4.pom mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) { // Spring Boot の BOM に定義されているバージョンから変更する場合には、ここに以下のように記述する // bomProperty "thymeleaf.version", "3.0.9.RELEASE" } mavenBom("org.junit:junit-bom:5.7.2") } } dependencies { def spockVersion = "2.0-groovy-3.0" .......... } .......... clean { doLast { rootProject.file("src/main/generated").deleteDir() rootProject.file("src/test/generated_tests").deleteDir() } } test { jvmArgs = jvmArgsForTask + jvmArgsAddOpens + ["-Dspring.profiles.active=unittest"] // for JUnit 5 useJUnitPlatform() testLogging { afterSuite printTestCount } } ..........
- dependencyManagement block の以下の点を変更します。
bomProperty "groovy.version", "2.5.12"
を削除します。これにより groovy のバージョンが 3.0.8 になります(Spring Boot 2.5.4 の Dependency Versions のorg.codehaus.groovy:groovy
参照)。
- dependencies block の以下の点を変更します。
def spockVersion = "1.3-groovy-2.5"
→def spockVersion = "2.0-groovy-3.0"
- テストが全て Junit 5 ベースになることにより testJUnit4AndSpock タスクが不要になるので、以下の記述を削除します。
task testJUnit4AndSpock(type: Test) { ... }
test.dependsOn testJUnit4AndSpock
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行をすると、Groovyc: unable to resolve class groovy.sql.Sql
というエラーが出力されました。
src/test/groovy/ksbysample/webapp/lending/SampleTest.groovy を見ると groovy.sql.Sql
が赤く表示されており package が存在しないようです。
Groovy Language Documentation Version 3.0.8 を見ると 3.8. Interacting with a SQL database に groovy-sql module が必要であるとの記述がありました。 build.gradle の dependencies block に testImplementation("org.codehaus.groovy:groovy-sql")
を追加します。
dependencies { .......... // dependency-management-plugin によりバージョン番号が自動で設定されるもの // Appendix F. Dependency versions ( https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-dependency-versions.html ) 参照 .......... testImplementation("org.yaml:snakeyaml") testImplementation("org.codehaus.groovy:groovy-sql") ..........
clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージが出力されました。
PowerMock で作成している static method のテストを Mockito で書き直して PowerMock を依存関係から削除する
src/test/groovy/ksbysample/webapp/lending/SampleHelperTest.groovy に記述した PowerMock で作成している static method のテストを、
package ksbysample.webapp.lending import org.junit.Test import org.junit.experimental.runners.Enclosed import org.junit.runner.RunWith import org.mockito.Mockito import org.powermock.api.mockito.PowerMockito import org.powermock.core.classloader.annotations.PowerMockIgnore import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunnerDelegate import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.junit4.SpringRunner import spock.lang.Specification import spock.lang.Unroll import javax.crypto.NoSuchPaddingException import static org.assertj.core.api.Assertions.assertThatExceptionOfType @RunWith(Enclosed) class SampleHelperTest { .......... @RunWith(PowerMockRunner) @PowerMockRunnerDelegate(SpringRunner) @SpringBootTest @PrepareForTest(BrowfishUtils) @PowerMockIgnore(["javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*"]) static class 異常処理のテスト { @Autowired private SampleHelper sampleHelper @Test void "SampleHelper_encryptを呼ぶとRuntimeExceptionをthrowする"() { // setup: PowerMockito.mockStatic(BrowfishUtils) PowerMockito.when(BrowfishUtils.encrypt(Mockito.any())) .thenThrow(new NoSuchPaddingException()) // expect: assertThatExceptionOfType(RuntimeException).isThrownBy({ sampleHelper.encrypt("test") }) } } }
以下のように変更します。
package ksbysample.webapp.lending import org.junit.experimental.runners.Enclosed import org.junit.jupiter.api.Test import org.junit.runner.RunWith import org.mockito.Mockito import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import spock.lang.Specification import spock.lang.Unroll import javax.crypto.NoSuchPaddingException import static org.assertj.core.api.Assertions.assertThatThrownBy @RunWith(Enclosed) class SampleHelperTest { .......... @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) } } }
Mockito で static method のテストを実装するには mockito-inline が必要なので、build.gradle の以下の点を変更します。
dependencies { .......... // dependency-management-plugin によりバージョン番号が自動で設定されるもの // Appendix F. Dependency versions ( https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-dependency-versions.html ) 参照 .......... testImplementation("org.codehaus.groovy:groovy-sql") testImplementation("org.mockito:mockito-inline")
- dependencies から以下の行を削除して PowerMock を依存関係から削除します。
def powermockVersion = "2.0.9"
testImplementation("org.powermock:powermock-module-junit4:${powermockVersion}")
testImplementation("org.powermock:powermock-api-mockito2:${powermockVersion}")
testImplementation("org.mockito:mockito-inline")
を追加します。
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
変更したテストを実行すると無事成功しました。
@Unroll アノテーションを削除する
Spock の Migration Guide の Unroll changes を読むと @Unroll アノテーションがなくても Data Driven テストが動作するようになったとのことなので、@Unroll アノテーションを削除します。
削除後に clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージが出力されて、テスト数も削除前と同じでした。
履歴
2021/08/29
初版発行。