前提
- SpringMVC 5.1.16
- Java11
- Junit4
- SpringTest 5.1.16
結論
実行用サンプル
別々の3項目、同じキーの2値、必須項目欠落を、フォームとBindingResultを通して確認します。 検証コードを見る。 JDK 17とMaven 3.9系で試せます。ソース・テスト・pom.xml・READMEをZIPに収録しています。
SampleFormController.java の全文
package info.syachiku.maintenance;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@RestController
class SampleFormController {
@PostMapping("/sample")
ResponseEntity<SampleForm> submit(@Valid @ModelAttribute SampleForm form, BindingResult errors) {
if (errors.hasErrors()) {
return ResponseEntity.badRequest().build();
}
return ResponseEntity.ok(form);
}
}
record SampleForm(@NotBlank String userid, @NotBlank String username,
@NotBlank String empno, List<String> roles) {
}テストは、個別指定で userid・username・empno が一致すること、一括指定で roles が2件になること、必須項目を外した場合に400となることを確認します。param() と params() はMockMvcのリクエストパラメーターを設定します。JSONの本文を送る場合は content() とメディアタイプを指定します。
MockMvc#performに指定するMockHttpServletRequestBuilderのparamまたはparamsを使いましょう。
paramsの場合、正確には以下のような構文になります。
MockMvcRequestBuilders.post("/sample").params(request)
変数requestの中に送信したいform情報を詰め込みます。
概要
SpringMVCのControllerのテストはSpringTestとJUnitの組み合わせでやるのが一般的だと思います。
Controller側が以下のようなフォームで待ち受けているとき
- ユーザーID(userid)
- ユーザー名(username)
- 社員番号(empno)
カッコ内はリクエスト項目名
mockMvc.performを使用して上記のフォーム情報を送信するには個別送信と一括送信が使用できます。
個別送信
paramメソッドを使って1個ずつ指定してやります。
mockMvc.perform(
MockMvcRequestBuilders.post("/sample").param("userid","user-01").param("username","TARO").param("empno","1365992")
)
少ない項目で、どの値を送るかをテスト本文から読みたい場合は param() が便利です。
一括送信
paramsを使ってまとめて指定します。
MultiValueMap<String, String> request = new LinkedMultiValueMap<String, String>();
List<String> list = new ArrayList<String>();
list.add("1365992");
request.put("empno",list);
List<String> list2 = new ArrayList<String>();
list2.add("user-01");
request.put("userid",list2);
List<String> list3 = new ArrayList<String>();
list3.add("TARO3");
request.put("username",list3);
mockMvc.perform(
MockMvcRequestBuilders.post("/sample").params(request)
)
同じ名前に複数の値を載せる場合は MultiValueMap に add() します。配布サンプルは roles に writer と reviewer の2値を追加し、Controllerが受け取る配列の順序まで確認します。
感想
項目数だけで使い分けを決める必要はありません。単発のケースでは param()、テストデータを組み立てて複数ケースへ渡すなら params() が使いやすくなります。
- 値を読む順で個別に指定するなら param()
- 入力データを組み立てて渡すなら params()
保存が伴うControllerなら、値のバインドに加え、入力エラー時に保存処理を呼ばないことも確かめます。
