かんがるーさんの日記

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

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その52 )( 入力画面3を作成する5 )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その51 )( 入力画面3を作成する4 ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • 入力画面3の作成
    • サーバ側のテストを作成します。

参照したサイト・書籍

目次

  1. InquiryInput03FormNotEmptyRule クラスのテストを作成する
  2. InquiryInputController クラスのテストを変更する
  3. 次回は。。。

手順

InquiryInput03FormNotEmptyRule クラスのテストを作成する

src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput03FormNotEmptyRule.java で Ctrl+Shift+T を押して「Create Test」ダイアログを表示してから、以下の画像の値にした後「OK」ボタンをクリックします。

f:id:ksby:20180526172038p:plain

src/test/groovy/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput03FormNotEmptyRuleTest.groovy が新規作成されるので、以下の内容を記述します。

package ksbysample.webapp.bootnpmgeb.web.inquiry.form

import ksbysample.webapp.bootnpmgeb.values.Type1Values
import ksbysample.webapp.bootnpmgeb.values.Type2Values
import spock.lang.Specification
import spock.lang.Unroll

import javax.validation.ConstraintViolation
import javax.validation.Validation

class InquiryInput03FormNotEmptyRuleTest extends Specification {

    def validator
    def inquiryInput03FormNotEmptyRule

    def setup() {
        validator = Validation.buildDefaultValidatorFactory().getValidator()
        inquiryInput03FormNotEmptyRule = new InquiryInput03FormNotEmptyRule(
                type1: Type1Values.PRODUCT.value
                , type2: [Type2Values.ESTIMATE.value, Type2Values.OTHER.value]
                , inquiry: "これはテストです"
                , survey: ["1", "2"]
        )
    }

    @Unroll
    def "type1 の NotEmpty のテスト(#type1 --> #size)"() {
        setup:
        inquiryInput03FormNotEmptyRule.type1 = type1
        Set<ConstraintViolation<InquiryInput03FormNotEmptyRule>> constraintViolations =
                validator.validate(inquiryInput03FormNotEmptyRule)

        expect:
        constraintViolations.size() == size

        where:
        type1                     || size
        ""                        || 1
        Type1Values.PRODUCT.value || 0
    }

    @Unroll
    def "type2 の NotEmpty のテスト(#type2 --> #size)"() {
        setup:
        inquiryInput03FormNotEmptyRule.type2 = type2
        Set<ConstraintViolation<InquiryInput03FormNotEmptyRule>> constraintViolations =
                validator.validate(inquiryInput03FormNotEmptyRule)

        expect:
        constraintViolations.size() == size

        where:
        type2                                                                              || size
        []                                                                                 || 1
        [Type2Values.ESTIMATE.value]                                                       || 0
        [Type2Values.ESTIMATE.value, Type2Values.CATALOGUE.value, Type2Values.OTHER.value] || 0
    }

    @Unroll
    def "inquiry の NotEmpty のテスト(#inquiry --> #size)"() {
        setup:
        inquiryInput03FormNotEmptyRule.inquiry = inquiry
        Set<ConstraintViolation<InquiryInput03FormNotEmptyRule>> constraintViolations =
                validator.validate(inquiryInput03FormNotEmptyRule)

        expect:
        constraintViolations.size() == size

        where:
        inquiry || size
        ""      || 1
        "テスト"   || 0
    }

}

テストを実行して全て成功することを確認します。

f:id:ksby:20180526181552p:plain

InquiryInputController クラスのテストを変更する

src/test/groovy/ksbysample/webapp/bootnpmgeb/web/inquiry/InquiryInputControllerTest.groovy の以下の点を変更します。

@RunWith(Enclosed)
class InquiryInputControllerTest {

    ..........

    @RunWith(SpringRunner)
    @SpringBootTest
    static class 入力画面3のテスト {
        private InquiryInput01Form inquiryInput01Form_001 =
                (InquiryInput01Form) new Yaml().load(getClass().getResourceAsStream("InquiryInput01Form_001.yaml"))
        private InquiryInput02Form inquiryInput02Form_001 = new InquiryInput02Form(
                zipcode1: "102"
                , zipcode2: "0072"
                , address: "東京都千代田区飯田橋1-1"
                , tel1: "03"
                , tel2: "1234"
                , tel3: "5678"
                , email: "taro.tanaka@sample.co.jp")
        private InquiryInput03Form inquiryInput03Form_001 = new InquiryInput03Form(
                type1: Type1Values.PRODUCT.value
                , type2: [Type2Values.ESTIMATE.value, Type2Values.CATALOGUE.value, Type2Values.OTHER.value]
                , inquiry: "これはテストです"
                , survey: ["1", "2", "3", "4", "5", "6", "7", "8"])

        @Autowired
        private WebApplicationContext context

        MockMvc mockMvc

        @Before
        void setup() {
            mockMvc = MockMvcBuilders.webAppContextSetup(context)
                    .build()
        }

        @Test
        void "初期表示時は画面の項目には何もセットされない"() {
            expect:
            mockMvc.perform(get("/inquiry/input/03"))
                    .andExpect(status().isOk())
                    .andExpect(html("select[name='type1'] option[selected]").notExists())
                    .andExpect(html("input[name='type2'][checked='checked']").notExists())
                    .andExpect(html("#inquiry").val(""))
                    .andExpect(html("input[name='survey'][checked='checked']").notExists())
        }

        @Test
        void "項目全てに入力して前の画面へ戻るボタンをクリックすると入力画面2へ戻り、次へ戻るボタンを押して入力画面3へ戻ると以前入力したデータがセットされて表示される"() {
            when: "入力画面1で項目全てに入力して「次へ」ボタンをクリックする"
            MvcResult result = mockMvc.perform(
                    TestHelper.postForm("/inquiry/input/01?move=next", inquiryInput01Form_001))
                    .andExpect(status().isFound())
                    .andExpect(redirectedUrlPattern("**/inquiry/input/02"))
                    .andReturn()
            MockHttpSession session = result.getRequest().getSession()

            and: "入力画面2で項目全てに入力して「次へ」ボタンをクリックする"
            mockMvc.perform(TestHelper.postForm("/inquiry/input/02?move=next", inquiryInput02Form_001)
                    .session(session))
                    .andExpect(status().isFound())
                    .andExpect(redirectedUrlPattern("**/inquiry/input/03"))

            and: "入力画面3で項目全てに入力して「前の画面へ戻る」ボタンをクリックする"
            mockMvc.perform(TestHelper.postForm("/inquiry/input/03?move=back", inquiryInput03Form_001)
                    .session(session))
                    .andExpect(status().isFound())
                    .andExpect(redirectedUrlPattern("**/inquiry/input/02"))

            and: "入力画面2で「次へ」ボタンをクリックする"
            mockMvc.perform(TestHelper.postForm("/inquiry/input/02?move=next", inquiryInput02Form_001)
                    .session(session))
                    .andExpect(status().isFound())
                    .andExpect(redirectedUrlPattern("**/inquiry/input/03"))

            then: "入力画面3が以前入力したデータがセットされて表示される"
            mockMvc.perform(get("/inquiry/input/03").session(session))
                    .andExpect(status().isOk())
                    .andExpect(html("select[name='type1'] option[selected]").val(inquiryInput03Form_001.type1))
                    .andExpect(html("input[name='type2'][checked='checked']").count(3))
                    .andExpect(html("#inquiry").val(inquiryInput03Form_001.inquiry))
                    .andExpect(html("input[name='survey'][checked='checked']").count(8))
        }

        @Test
        void "項目全てに入力して次へボタンをクリックすると確認画面へ遷移し、前の画面へ戻るボタンを押して入力画面3へ戻ると以前入力したデータがセットされて表示される"() {
            expect:
            assert false, "確認画面を実装してからテストを作成する"
        }

        @Test
        void "入力チェックエラーのあるデータで「次へ」ボタンをクリックするとIllegalArgumentExceptionが発生する"() {
            setup: "入力チェックエラーになるデータを用意する"
            inquiryInput03Form_001.type1 = ""

            expect: "入力画面3の「次へ」ボタンをクリックする"
            Throwable thrown = catchThrowable({
                mockMvc.perform(
                        TestHelper.postForm("/inquiry/input/03?move=next", inquiryInput03Form_001))
                        .andExpect(status().isOk())
            })
            assertThat(thrown.cause).isInstanceOf(IllegalArgumentException)
        }

    }

}
  • 入力画面3のテスト クラスを追加します。
  • 項目全てに入力して次へボタンをクリックすると確認画面へ遷移し、前の画面へ戻るボタンを押して入力画面3へ戻ると以前入力したデータがセットされて表示される のテストは確認画面を実装しないとテストを作成できなかったので、今は常に失敗するようにします。

テストを実行して1つを除き成功することを確認します。

f:id:ksby:20180526193719p:plain

次回は。。。

確認画面を作成するか、以下3つのどれかをやりたいと思います。

履歴

2018/05/26
初版発行。