

現在springbootアプリケーションを作成していて、表題の通りformに複数のsubmitボタンを配置しています。  
その対象となるControllerメソッドに対して単体テストを行いたいのですが、リクエストがうまく通らず403エラーが返ってきてしまいます。  
テストコードから403エラーにならずにリクエストを正常に投げられるようにしたいのですが解決方法がわかりません。

### 試したこと

以下の参考記事によると、formに複数のsubmitボタンが配置されると、name属性のついたsubmitボタンの値もリクエストボディーに入るとのこと（Google
Chromeデベロッパーツールでも確認しました）だった為、ExampleFormEx1/ExampleFormEx2をテスト用に作成してテストでリクエストしてみましたがダメでした。

**参考:**  
[Springで複数のsubmitボタン対応](https://qiita.com/NagaokaKenichi/items/3a4486cb6f32a3c9d69f)

どう直せば良いか教えていただけますと幸いです。

**環境:**

  * Java11
  * SpringBoot2.3.6
  * Thymeleaf

* * *

### ソースコード

**ExampleController.java**

[code]

    @Controller
    public class ExampleController {
        @GetMapping("/")
        public init() {
    
            // ...処理...
    
            return "example.html";
        }
    
        @PostMapping(value = "/", params = "ex1")
        public postEx1(ExampleForm form) {
    
            // ...処理...
    
            return "example.html";
        }
    
        @PostMapping(value = "/", params = "ex2")
        public postEx2(ExampleForm form) {
    
            // ...処理...
    
            return "example.html";
        }
    }
    
[/code]

**ExampleForm.java**

[code]

    @Getter
    @Setter
    public class ExampleForm {
        private String fullName;
        private Integer age;
    }
    
[/code]

**example.html**

[code]

    <body>
      <form action="/" method="POST">
        <input type="text" name="fullName" />
        <input type="number" name="age" />
        <button type="submit" name="ex1">ex1へ送信</button>
        <button type="submit" name="ex2">ex2へ送信</button>
      </form>
    </body>
    
[/code]

**ExampleControllerTest.java**

[code]

    @SpringBootTest(webEnviroment = WebEnviroment.DIFINED_PORT)
    @AutoConfigureMockMvc
    public class ExampleControllerTest {
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        public void postEx1Test() {
            ExampleFormEx1 form = new ExampleFormEx1();
            form.setFullName("テスト太郎");
            form.setAge(20);
            form.setEx1("");
            String requestForm = new ObjectMapper().writeValueAsString(form)
    
            MockHttpServletRequestBuilder request = MockMvcRequestBuilders
                    .post("/")
                    .content(requestForm)
                    .accept("application/json;charset=UTF-8")
                    .contentType("MediaType.APPLICATION_JSON");
            MvcResult result = mockMvc.perform(request)
                    .andExcept(status().isOk())
                    .andExcept(view.name("example.html"))
                    .andReturn();
    
            // ...テスト処理...
    
        }
    
        @Test
        public void postEx2Test() {
            ExampleFormEx2 form = new ExampleFormEx2();
            form.setFullName("テスト花子");
            form.setAge(30);
            form.setEx2("");
            String requestForm = new ObjectMapper().writeValueAsString(form)
    
            MockHttpServletRequestBuilder request = MockMvcRequestBuilders
                    .post("/")
                    .content(requestForm)
                    .accept("application/json;charset=UTF-8")
                    .contentType("MediaType.APPLICATION_JSON");
            MvcResult result = mockMvc.perform(request)
                    .andExcept(status().isOk())
                    .andExcept(view.name("example.html"))
                    .andReturn();
    
            // ...テスト処理...
    
        }
    }
    
[/code]

**ExampleFormEx1.java**

[code]

    @Getter
    @Setter
    public class ExampleFormEx1 extends ExampleForm {
        private String ex1;
    }
    
[/code]

**ExampleFormEx2.java**

[code]

    @Getter
    @Setter
    public class ExampleFormEx2 extends ExampleForm {
        private String ex2;
    }
    
[/code]


CC BY-SA 4.0
2021-09-08T10:03:54.817
82349
2023-08-23T10:00:18.263
2021-09-08T16:49:49.240
3060
47269
question
java spring-boot thymeleaf junit mockito
jUnit/Springboot 複数submitボタンを配置したcontrollerのテストができない


form を submit するときの `Content-Type` は `application/json` ではなく
`application/x-www-form-urlencoded` です。  
また、設定すべきリクエストボディは Chrome の devtools で確認できます(view source ボタンを押すと生データが見られます)。

[code]

    mockMvc.perform(post("/")
        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
        // https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.html#content-java.lang.String-
        .content("fullName=%E3%83%86%E3%82%B9%E3%83%88%E5%A4%AA%E9%83%8E&age=20&ex1=")
        // あるいは param() を使って
        // .param("fullName", "テスト太郎")
        // .param("age", "20")
        // .param("ex1", "")
        )
        .andExpect(status().isOk())
        .andExpect(view().name("example.html"));
    
[/code]


CC BY-SA 4.0
2021-09-08T16:46:59.523
82360
2021-09-08T16:55:09.820
2021-09-08T16:55:09.820
2808
2808
82349
answer