かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その38 )( 貸出申請画面の作成9 )

概要

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その37 )( 貸出申請画面の作成8 ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • 貸出申請画面の作成
      • テストの作成 ( 2回に分けて書きます )
    • Parameterized test が書きやすい Spock というテスティングフレームワークがあると聞き、ドキュメントや使用例を見てみると確かに分かりやすそうだったので、今回いくつかのクラスのテストで使ってみたいと思います。

参照したサイト・書籍

  1. spock
    https://code.google.com/p/spock/

    • Spock Framework のホームページです。ドキュメントはこのサイトにあります。
  2. GitHub - spockframework/spock
    https://github.com/spockframework/spock

    • Spock Framework の GitHub です。
  3. JavaユニットテストにSpockを適用する
    http://qiita.com/euno7/items/1e834d3d58da3e659f92

    • こちらの記事を見て Spock の Parameterized test が書きやすそうに思えました。今回実装時も参考にしています。
  4. Spock Framework - データ駆動テスト
    https://spock-framework-reference-documentation-ja.readthedocs.org/ja/latest/data_driven_testing.html

    • Spock Framework について日本語で分かりやすく説明されているドキュメントです。
    • ただし、まだ作成中とのことです。
  5. プログラミングGROOVY

    プログラミングGROOVY

    プログラミングGROOVY

    • Groovy を覚えるために買ってきました。
  6. Java開発の強力な相棒として今すぐ使えるGroovy
    http://www.slideshare.net/nobeans/javagroovy

    • Groovy について分かりやすく解説されているスライドです。
  7. Groovy - Differences with Java
    http://www.groovy-lang.org/differences.html

    • Groovy のホームページの Documentation で Java との比較が記載されています。
  8. 40.3.1 Using Spock to test Spring Boot applications
    https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-with-spock

    • Spring Boot のドキュメントに Spock によるテストについて記載されています。
  9. Integration Test with Spring Boot and Spock
    http://stackoverflow.com/questions/24405727/integration-test-with-spring-boot-and-spock

    • Spock のテストで @Autowired を使用する方法を調査した時に参照しました。

目次

  1. テスト作成対象のクラスを決める
  2. EmailHelperTest クラスのパッケージを変更する
  3. printClassWhatNotMakeTest タスクのチェック対象外のパッケージを設定する
  4. Spock を利用できるようにする
  5. SuccessMessagesHelper クラスのテストの作成
  6. CookieUtils クラスのテストの作成
  7. ValuesHelper クラスのテストの作成
  8. compareSrcAndTestDir タスクで src/test/groovy をチェック対象にする
  9. 全てのテストが成功するか確認する
  10. Spock を使ってみた感想

手順

テスト作成対象のクラスを決める

  1. Gradle projects View から printClassWhatNotMakeTest タスクを実行します。

    f:id:ksby:20151226081329p:plain

  2. 出力されたクラスに対して以下の対応を行います。

    • EmailHelper のテストクラス EmailHelperTest はリファクタリング時にクラス名は変更されましたが、配置場所が src/test/java/ksbysample/webapp/lending/service のままでしたので適切な場所に移動します。
      • src/main/java/ksbysample/webapp/lending/helper/mail/EmailHelper.java
    • 以下のパッケージは printClassWhatNotMakeTest タスクのチェック対象外にします。
    • 以下のクラスは Spock でテストを作成します。
      • src/main/java/ksbysample/webapp/lending/helper/thymeleaf/SuccessMessagesHelper.java
      • src/main/java/ksbysample/webapp/lending/util/cookie/CookieUtils.java
      • src/main/java/ksbysample/webapp/lending/values/ValuesHelper.java
    • 以下のクラスは JUnit でテストを作成します。
      • src/main/java/ksbysample/webapp/lending/helper/mail/Mail002Helper.java
      • src/main/java/ksbysample/webapp/lending/helper/user/UserHelper.java
      • src/main/java/ksbysample/webapp/lending/web/ExceptionHandlerAdvice.java
      • src/main/java/ksbysample/webapp/lending/web/lendingapp/LendingappController.java
      • src/main/java/ksbysample/webapp/lending/web/lendingapp/LendingappFormValidator.java
      • src/main/java/ksbysample/webapp/lending/web/lendingapp/LendingappService.java
      • src/main/java/ksbysample/webapp/lending/web/lendingapp/LendingBookDto.java
      • src/main/java/ksbysample/webapp/lending/web/WebappErrorController.java

EmailHelperTest クラスのパッケージを変更する

  1. src/test/java/ksbysample/webapp/lending/service の下の EmailHelperTest クラスを src/test/java/ksbysample/webapp/lending/helper/mail へ Drag&Drop します。「Move」ダイアログが表示されますので「Refactor」ボタンをクリックします。

    f:id:ksby:20151226220318p:plain

  2. テストが動作するか実行して確認します。Project View 上で移動した EmailHelperTest クラスを選択してコンテキストメニューを表示後「Run 'EmailHelperTest' with Coverage」を選択します。

    テストが成功することが確認できます。

    f:id:ksby:20151226220823p:plain

printClassWhatNotMakeTest タスクのチェック対象外のパッケージを設定する

  1. build.gradle を リンク先のその1の内容 に変更します。

Spock を利用できるようにする

  1. build.gradle を リンク先のその2の内容 に変更します。

  2. Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。更新が完了すると Project View に src/main/groovy, src/test/groovy ディレクトリが表示されます。

    src/main/groovy, src/test/groovy の下にファイルを作成してから、その後でディレクトリの下のファイルを全て削除すると IntelliJ IDEA の機能によりこれらのディレクトリが表示されなくなりますが、その場合には Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すれば再び表示されます。

    f:id:ksby:20151226213819p:plain

SuccessMessagesHelper クラスのテストの作成

  1. src/main/java/ksbysample/webapp/lending/helper/thymeleaf の下の SuccessMessagesHelper.java で「Create Test」ダイアログを表示し、テストクラスを作成します。

    今回気付きましたが、「Testing library」で "Spock" が選択可能になっていますね。IDEA 便利です。

    ※「Spock Framework Enhancements」という Plugin がありますが、これをインストールすると「Create Test」ダイアログの「Tesing library」に "Spock" という選択項目が2つ表示されますのでインストールしません。IntelliJ IDEA の 14 でインストールしている例を見かけましたが、15 ではインストールする必要はなさそうです。

    f:id:ksby:20151226222411p:plain

    「OK」ボタンをクリックすると「Choose Destination Directory」が表示されますので、「...\src\test\groovy\」の方を選択して「OK」ボタンをクリックします。

    f:id:ksby:20151226222629p:plain

  2. src/test/groovy/ksbysample/webapp/lending/helper/thymeleaf の下に SuccessMessagesHelperTest.groovy が作成されますので、リンク先の内容 に変更します。

  3. テストを実行します。SuccessMessagesHelperTest クラスのクラス名の左側に表示されているアイコンをクリックしてコンテキストメニューを表示後「Run 'SuccessMessagesHelperTest' with Coverage」を選択します。

    テストが成功することが確認できます。

    f:id:ksby:20151227083508p:plain

    Coverage も問題なく計測できています。

    f:id:ksby:20151227083655p:plain

CookieUtils クラスのテストの作成

  1. src/main/java/ksbysample/webapp/lending/util/cookie の下の CookieUtils.java で「Create Test」ダイアログを表示し、テストクラスを作成します。

    f:id:ksby:20151227085427p:plain

  2. src/test/groovy/ksbysample/webapp/lending/util/cookie の下に CookieUtilsTest.groovy が作成されますので、リンク先の内容 に変更します。

  3. テストを実行します。CookieUtilsTest クラスのクラス名の左側に表示されているアイコンをクリックしてコンテキストメニューを表示後「Run 'CookieUtilsTest' with Coverage」を選択します。

    テストが成功することが確認できます。

    f:id:ksby:20151227145600p:plain

ValuesHelper クラスのテストの作成

  1. src/main/java/ksbysample/webapp/lending/values の下の ValuesHelper.java で「Create Test」ダイアログを表示し、テストクラスを作成します。

    f:id:ksby:20151227145839p:plain

  2. src/test/groovy/ksbysample/webapp/lending/values の下に ValuesHelperTest.groovy が作成されますので、リンク先の内容 に変更します。

  3. テストを実行します。ValuesHelperTest クラスのクラス名の左側に表示されているアイコンをクリックしてコンテキストメニューを表示後「Run 'ValuesHelperTest' with Coverage」を選択します。

    テストが成功することが確認できます。

    f:id:ksby:20151227155635p:plain

compareSrcAndTestDir タスクで src/test/groovy をチェック対象にする

compareSrcAndTestDir タスクでテストクラスが存在するかチェックするディレクトリに src/test/groovy を追加します。

  1. build.gradle を リンク先のその3の内容 に変更します。

  2. 動作確認します。Gradle projects View から printClassWhatNotMakeTest タスクを実行します。今回テストクラスを作成したクラスが表示されないことを確認できます。

    f:id:ksby:20151227162353p:plain

全てのテストが成功するか確認する

  1. 全てのテストが成功するか確認してみます。Project View のルートでコンテキストメニューを表示して「Run 'Tests in 'ksbysample...' with Coverage」を選択します。

    今回作成したものではないテストが2つ失敗しましたが、JUnit と Spock で作成したテストがどちらも実行されていること、Spock で作成したテストが特に遅くなったりはしないことを確認できます。

    f:id:ksby:20151227200007p:plain

    失敗したテストの原因を調査します。

  2. 原因は2つとも TableDataAssert::assertEquals メソッドで lending_app, lending_book テーブルのデータを比較しているところで 追加した version カラムも比較対象になっているためでした。比較対象のカラム数が異なりテストが失敗していました。version カラムを比較の対象から外します。

  3. src/test/java/ksbysample/webapp/lending/listener/rabbitmq の下の InquiringStatusOfBookQueueListenerTest.javaリンク先の内容 に変更します。

  4. src/test/java/ksbysample/webapp/lending/web/booklist の下の BooklistServiceTest.javaリンク先の内容 に変更します。

  5. 再度テストを実行します。今度は全て成功することが確認できます。

    f:id:ksby:20151227203053p:plain

  6. 一旦 commit します。

Spock を使ってみた感想

  • テストが書きやすいですね。特にパラメータ化テストが分かりやすい&書きやすいです。JUnit実践入門を読んだ時はパラメータ化テストの何が便利なのか全く理解できなかったのですが、Spock の実装例を見て使い方が理解できました。
    JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

    JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

  • Spring Boot のドキュメントにも簡単ですが Spock によるテストについて記載されています。また Appendix E. Dependency versions に記載があるので、他のライブラリと比較するとサポートが考慮されていると思われます。
  • IntelliJ IDEA で「Create Test」ダイアログのテスティングフレームワークの選択肢に Spock がデフォルトで表示されており、こちらでも考慮されているようです。
  • build.gradle の dependencies タスクに org.spockframework:spock-spring を記載すれば @Autowired が必要となるテストも作成できます。
  • IntelliJ IDEA でサポートされているのでテストクラスを作成する時の手間は JUnit と変わりがありません。ただし build.gradle への記述内容と、テストクラスを src/test/java ではなく src/test/groovy の下に作成することは覚えておかないといけませんが ( 今回もこの点は調査に時間がかかりました )。
  • 全面的に JUnit → Spock へ移行するかはまだ触ったばかりなので決められませんが、少なくとも DB 処理を伴わないクラスのテストは Spock へ移行して構わないと思いました。テストでも手軽に書きたいものは時間をかけずにさっと書きたいと思っていたので、Spock は非常にいいと思います。
  • ちょっどよいタイミングで年末に「Java Testing With Spock」という本が出るようなので買って読んでみたいと思います。

ソースコード

build.gradle

■その1

task printClassWhatNotMakeTest << {
    def srcDir = new File("src/main/java");
    def excludePaths = [
            "src/main/java/ksbysample/webapp/lending/Application.java"
            , "src/main/java/ksbysample/webapp/lending/config"
            , "src/main/java/ksbysample/webapp/lending/cookie"
            , "src/main/java/ksbysample/webapp/lending/dao"
            , "src/main/java/ksbysample/webapp/lending/entity"
            , "src/main/java/ksbysample/webapp/lending/exception"
            , "src/main/java/ksbysample/webapp/lending/helper/page/PagenationHelper.java"
            , "src/main/java/ksbysample/webapp/lending/security/LendingUser.java"
            , "src/main/java/ksbysample/webapp/lending/security/RoleAwareAuthenticationSuccessHandler.java"
            , "src/main/java/ksbysample/webapp/lending/service/calilapi/response"
            , "src/main/java/ksbysample/webapp/lending/service/file/BooklistCSVRecord.java"
            , "src/main/java/ksbysample/webapp/lending/service/openweathermapapi"
            , "src/main/java/ksbysample/webapp/lending/service/queue/InquiringStatusOfBookQueueMessage.java"
            , "src/main/java/ksbysample/webapp/lending/util/doma"
            , "src/main/java/ksbysample/webapp/lending/util/velocity/VelocityUtils.java"
            , "src/main/java/ksbysample/webapp/lending/webapi/common/CommonWebApiResponse.java"
            , "src/main/java/ksbysample/webapp/lending/webapi/weather"
    ];
    def excludeFileNamePatterns = [
            ".*EventListener.java"
            , ".*Form.java"
            , ".*Values.java"
    ];

    compareSrcAndTestDir(srcDir, excludePaths, excludeFileNamePatterns);
}
  • excludePaths に , "src/main/java/ksbysample/webapp/lending/cookie" を追加します。

■その2

buildscript {
    ext {
        springBootVersion = '1.2.7.RELEASE'
    }
    repositories {
        jcenter()
        maven { url "http://repo.spring.io/repo/" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("io.spring.gradle:dependency-management-plugin:0.5.3.RELEASE")
        // for Grgit
        classpath("org.ajoberstar:grgit:1.4.1")
        // Gradle Download Task
        classpath("de.undercouch:gradle-download-task:2.0.0")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'de.undercouch.download'
apply plugin: 'groovy'

sourceCompatibility = 1.8
targetCompatibility = 1.8

compileJava.options.compilerArgs = ['-Xlint:all']

// for Doma 2
// JavaクラスとSQLファイルの出力先ディレクトリを同じにする
processResources.destinationDir = compileJava.destinationDir
// コンパイルより前にSQLファイルを出力先ディレクトリにコピーするために依存関係を逆転する
compileJava.dependsOn processResources

jar {
    baseName = 'ksbysample-webapp-lending'
    version = '1.0.0-SNAPSHOT'
}

eclipse {
    classpath {
        containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
        containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
    }
}

idea {
    module {
        inheritOutputDirs = false
        outputDir = file("$buildDir/classes/main/")
    }
}

configurations {
    domaGenRuntime
}

repositories {
    jcenter()
}

dependencies {
    def jdbcDriver = "org.postgresql:postgresql:9.4-1204-jdbc41"

    // spring-boot-gradle-plugin によりバージョン番号が自動で設定されるもの
    // Appendix E. Dependency versions ( http://docs.spring.io/spring-boot/docs/current/reference/html/appendix-dependency-versions.html ) 参照
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity3")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-velocity")
    compile("org.springframework.boot:spring-boot-starter-mail")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-redis")
    compile("org.springframework.boot:spring-boot-starter-amqp")
    compile("org.codehaus.janino:janino")
    compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
    compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
    testCompile("org.springframework.boot:spring-boot-starter-test")
    // (ここから) gradle でテストを実行した場合に spring-security-test-4.0.2.RELEASE.jar しか classpath に指定されず
    // テストが失敗したため、3.2.8.RELEASE を明記している
    testCompile("org.springframework.security:spring-security-core:3.2.8.RELEASE")
    testCompile("org.springframework.security:spring-security-web:3.2.8.RELEASE")
    // (ここまで) ------------------------------------------------------------------------------------------------------
    testCompile("org.springframework.security:spring-security-test:4.0.2.RELEASE")
    testCompile("org.yaml:snakeyaml")
    testCompile("org.codehaus.groovy:groovy-all")
    testCompile("org.spockframework:spock-core")
    testCompile("org.spockframework:spock-spring")

    // spring-boot-gradle-plugin によりバージョン番号が自動で設定されないもの
    compile("${jdbcDriver}")
    compile("org.seasar.doma:doma:2.5.0")
    compile("org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16")
    compile("org.apache.commons:commons-lang3:3.4")
    compile("org.projectlombok:lombok:1.16.6")
    compile("com.google.guava:guava:18.0")
    compile("org.springframework.session:spring-session:1.0.1.RELEASE")
    compile("org.simpleframework:simple-xml:2.7.1")
    compile("com.univocity:univocity-parsers:1.5.6")
    compile("org.thymeleaf.extras:thymeleaf-extras-java8time:2.1.0.RELEASE")
    testCompile("org.dbunit:dbunit:2.5.1")
    testCompile("com.icegreen:greenmail:1.4.1")
    testCompile("org.assertj:assertj-core:3.2.0")
    testCompile("com.jayway.jsonpath:json-path:2.0.0")
    testCompile("org.jmockit:jmockit:1.19")

    // for Doma-Gen
    domaGenRuntime("org.seasar.doma:doma-gen:2.5.0")
    domaGenRuntime("${jdbcDriver}")
}
  • apply plugin: 'groovy' を追加します。
  • testCompile("org.spockframework:spock-core") を追加します。
  • testCompile("org.spockframework:spock-spring") を追加します。

■その3

def compareSrcAndTestDir(srcDir, excludePaths, excludeFileNamePatterns) {
    def existFlg
    def testDirAndTestClassNameList = [
            ["src/test/java", "Test.java"]
            , ["src/test/groovy", "Test.groovy"]
    ]

    for (srcFile in srcDir.listFiles()) {
        String srcFilePath = (srcFile.toPath() as String).replaceAll("\\\\", "/")
        existFlg = false

        for (exclude in excludePaths) {
            if (srcFilePath =~ /^${exclude as String}/) {
                existFlg = true
                break
            }
        }
        if (existFlg == true) continue

        for (exclude in excludeFileNamePatterns) {
            if (srcFilePath =~ /${exclude as String}/) {
                existFlg = true
                break
            }
        }
        if (existFlg == true) continue
        
        if (srcFile.isDirectory()) {
            compareSrcAndTestDir(srcFile, excludePaths, excludeFileNamePatterns)
        } else {
            def nextFlg = false
            for (testDirAndTestClassName in testDirAndTestClassNameList) {
                def testDir = testDirAndTestClassName[0]
                def testClassName = testDirAndTestClassName[1]

                String testFilePath = srcFilePath.replaceFirst(/^src\/main\/java/, testDir).replaceFirst(/\.java$/, testClassName)
                def testFile = new File(testFilePath)
                if (testFile.exists()) {
                    nextFlg = true
                    break
                }
            }
            if (nextFlg) continue

            println(srcFilePath);
        }
    }
}
  • compareSrcAndTestDir タスクを上記の実装に変更します。

SuccessMessagesHelperTest.groovy

package ksbysample.webapp.lending.helper.thymeleaf

import org.springframework.ui.ExtendedModelMap
import spock.lang.Specification

class SuccessMessagesHelperTest extends Specification {

    def "SuccessMessagesHelperTestのテスト_コンストラクタを使用する場合"() {
        setup:
        def model = new ExtendedModelMap()

        expect:
        def successMessagesHelper = new SuccessMessagesHelper(str);
        successMessagesHelper.setToModel(model)
        model.get("successMessages") == result

        where:
        str                           || result
        "コンストラクタで追加する" || ["コンストラクタで追加する"]
    }

    def "SuccessMessagesHelperTestのテスト_addMsgを使用する場合"() {
        setup:
        def successMessagesHelper = new SuccessMessagesHelper();
        def model = new ExtendedModelMap()

        expect:
        for (str in list) {
            successMessagesHelper.addMsg(str)
        }
        successMessagesHelper.setToModel(model)
        model.get("successMessages") == result

        where:
        list                                                 || result
        ["1つ追加する"]                                    || ["1つ追加する"]
        ["2つ追加する(1つ目)", "2つ追加する(2つ目)"] || ["2つ追加する(1つ目)", "2つ追加する(2つ目)"]
    }

}

CookieUtilsTest.groovy

package ksbysample.webapp.lending.util.cookie

import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.web.util.CookieGenerator
import spock.lang.Specification

import javax.servlet.http.Cookie

class CookieUtilsTest extends Specification {

    static class CookieTest extends CookieGenerator {
        public static final String COOKIE_NAME = "TestCookie";
        public CookieTest() {
            setCookieName(COOKIE_NAME);
        }
    }

    static class CookieSample extends CookieGenerator {
        public static final String COOKIE_NAME = "SampleCookie";
        public CookieSample() {
            setCookieName(COOKIE_NAME);
        }
    }

    def "AddCookie_and_RemoveCookie_Cookieが1個の場合"() {
        setup:
        def response = new MockHttpServletResponse()
        
        expect:
        CookieUtils.addCookie(CookieTest.class, response, "テスト")
        Cookie[] cookies = response.getCookies()
        cookies.size() == 1
        cookies[0].name == CookieTest.COOKIE_NAME
        cookies[0].value == "テスト"
        CookieUtils.removeCookie(CookieTest.class, response)
        Cookie[] cookies2 = response.getCookies()
        cookies2[0].maxAge == -1
    }

    def "AddCookie_and_RemoveCookie_Cookieが2個の場合"() {
        setup:
        def response = new MockHttpServletResponse()

        expect:
        CookieUtils.addCookie(CookieTest.class, response, "テスト")
        CookieUtils.addCookie(CookieSample.class, response, "サンプル")
        Cookie[] cookies = response.getCookies()
        cookies.size() == 2
        for (cookie in cookies) {
            if (cookie.name == CookieTest.COOKIE_NAME) {
                cookie.value == "テスト"
            }
            else if (cookie.name == CookieSample.COOKIE_NAME) {
                cookie.value == "サンプル"
            }
        }
        CookieUtils.removeCookie(CookieSample.class, response)
        Cookie[] cookies2 = response.getCookies()
        for (cookie in cookies) {
            if (cookie.name == CookieSample.COOKIE_NAME) {
                cookie.maxAge == -1
            }
            else {
                cookie.maxAge != -1
            }
        }
    }

    def "GetCookieValueのテスト"() {
        setup:
        def request = new MockHttpServletRequest()
        
        expect:
        Cookie cookieTest = new Cookie(CookieTest.COOKIE_NAME, "テスト")
        Cookie cookieSample = new Cookie(CookieSample.COOKIE_NAME, "サンプル")
        request.setCookies(cookieTest, cookieSample)
        CookieUtils.getCookieValue(CookieTest.COOKIE_NAME, request) == "テスト"
        CookieUtils.getCookieValue(CookieSample.COOKIE_NAME, request) == "サンプル"
    }

}

ValuesHelperTest.groovy

package ksbysample.webapp.lending.values

import ksbysample.webapp.lending.Application
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.SpringApplicationContextLoader
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.web.WebAppConfiguration
import spock.lang.Specification
import spock.lang.Unroll

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = Application.class)
@WebAppConfiguration
class ValuesHelperTest extends Specification {

    @Autowired
    ValuesHelper vh;

    @Unroll
    def "GetValue(#classSimpleName, #valueName) --> #result"() {
        expect:
        vh.getValue(classSimpleName, valueName) == result

        where:
        classSimpleName                       | valueName           || result
        "LendingAppStatusValues"          | "TENPORARY_SAVE" || "1"
        "LendingAppStatusValues"          | "PENDING"         || "3"
        "LendingBookLendingAppFlgValues" | "NOT_APPLY"       || ""
    }

    @Unroll
    def "GetText(#classSimpleName, #value) --> #result"() {
        expect:
        vh.getText(classSimpleName, value) == result
        
        where:
        classSimpleName                       | value || result
        "LendingAppStatusValues"          | "1"   || "一時保存"
        "LendingAppStatusValues"          | "3"   || "申請中"
        "LendingBookLendingAppFlgValues" | ""    || "しない"
    }

    @Unroll
    def "Values(#classSimpleName)"() {
        expect:
        vh.values(classSimpleName) == result

        where:
        classSimpleName                       || result
        "LendingAppStatusValues"          || LendingAppStatusValues.values()
        "LendingBookLendingAppFlgValues" || LendingBookLendingAppFlgValues.values()
    }
}

InquiringStatusOfBookQueueListenerTest.java

    @Test
    @TestDataLoader("src/test/resources/ksbysample/webapp/lending/listener/rabbitmq/testdata/001")
    public void testReceiveMessage() throws Exception {

        ..........

            /**
             * 検証
             */
            // テーブルの以下のカラムのデータを検証する
            //  ・lending_app.status
            //  ・lending_book.lending_state
            IDataSet dataSet = new CsvDataSet(new File("src/test/resources/ksbysample/webapp/lending/listener/rabbitmq/assertdata/001"));
            TableDataAssert tableDataAssert = new TableDataAssert(dataSet, dataSource);
            tableDataAssert.assertEquals("lending_app", new String[]{"lending_app_id", "lending_user_id", "approval_user_id", "version"});
            tableDataAssert.assertEquals("lending_book", new String[]{"lending_book_id", "lending_app_id", "isbn", "book_name", "lending_app_flg", "lending_app_reason", "approval_result", "approval_reason", "version"});


        ..........
    }

}
  • testReceiveMessage メソッド内の tableDataAssert.assertEquals("lending_app", ...);tableDataAssert.assertEquals("lending_book", ...); で比較対象外のカラムを第2引数で指定している最後に , "version" を追加します。

BooklistServiceTest.java

    @Test
    public void testTemporarySaveBookListCsvFile() throws Exception {
        new NonStrictExpectations(LendingUserDetailsHelper.class) {{
            LendingUserDetailsHelper.getLoginUserId(); result = new Long(1);
        }};

        UploadBooklistForm uploadBooklistForm = new UploadBooklistForm();
        // テスト用のユーティリティクラスを作るべきですが、今回は他のテストクラスのメソッドをそのまま使います
        BooklistCsvFileServiceTest booklistCsvFileServiceTest = new BooklistCsvFileServiceTest();
        uploadBooklistForm.setFileupload(booklistCsvFileServiceTest.createNoErrorCsvFile());
        
        Long lendingAppId = booklistService.temporarySaveBookListCsvFile(uploadBooklistForm);
        assertThat(lendingAppId).isNotEqualTo(new Long(0));
        IDataSet dataSet = new CsvDataSet(new File("src/test/resources/ksbysample/webapp/lending/web/booklist/assertdata/001"));
        TableDataAssert tableDataAssert = new TableDataAssert(dataSet, dataSource);
        tableDataAssert.assertEquals("lending_app", new String[]{"lending_app_id", "approval_user_id", "version"});
        tableDataAssert.assertEquals("lending_book", new String[]{"lending_book_id", "lending_app_id", "lending_state", "lending_app_flg", "lending_app_reason", "approval_result", "approval_reason", "version"});

        List<LendingBook> lendingBookList = booklistService.getLendingBookList(lendingAppId);
        assertThat(lendingBookList).hasSize(5);
    }

}
  • testTemporarySaveBookListCsvFile メソッド内の tableDataAssert.assertEquals("lending_app", ...);tableDataAssert.assertEquals("lending_book", ...); で比較対象外のカラムを第2引数で指定している最後に , "version" を追加します。

履歴

2015/12/27
初版発行。