MockMvcとは、アプリケーションサーバ上にデプロイすることなくSpring MVCの動作を再現できるフレームワークで、コントローラクラスのテストを行う際に利用することができる。
今回は、MockMvcを利用したコントローラクラスのテストクラスを作成してみたので、共有する。
なお、MockMvcについての詳細は、以下のサイトを参照のこと。
https://terasolunaorg.github.io/guideline/5.4.1.RELEASE/ja/UnitTest/ImplementsOfUnitTest/UsageOfLibraryForTest.html#usageoflibraryfortestmockmvcoverview
前提条件
下記記事の実装が完了していること。
ユーティリティクラスの良い例と悪い例を実装してみたごく単純なJavaクラスの実装であっても、実装方法はいくつか考えられるため、その中で「最も良い」実装方法を検討し選択する必要がある。今回...
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。
今回のテスト対象となるコントローラクラスの内容は以下の通り。
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Controller
public class DemoController {
/**
* ハッシュマップをセッションに追加し、初期表示画面に遷移
* @param request HttpServletRequestオブジェクト
* @return 初期表示画面へのパス
*/
@GetMapping("/")
public String index(HttpServletRequest request){
// セッションを生成
HttpSession session = request.getSession(true);
// ハッシュマップを生成し、セッションに追加
HashMap<String, List<String>> hashMap = createHashMap();
session.setAttribute("sesHashMap", hashMap);
return "index";
}
/**
* セッションから指定したキー値に対応するリストを取得し、次画面に遷移
* @param model Modelオブジェクト
* @param request HttpServletRequestオブジェクト
* @return 次画面へのパス
*/
@PostMapping("/next")
public String next(Model model, HttpServletRequest request){
// セッションから指定したキー値に対応するリストを取得し、sessionListに設定
List<String> hashList = DemoUtil.getHashList("key1");
model.addAttribute("sessionList", hashList);
// セッションの値を破棄し、次画面に遷移
request.getSession(false).invalidate();
return "next";
}
/**
* セッションに設定するハッシュマップを生成する
* @return 生成したハッシュマップ
*/
private HashMap<String, List<String>> createHashMap(){
HashMap<String, List<String>> hashMap = new HashMap<>();
List<String> hashList1 = new ArrayList<>();
hashList1.add("item1");
hashList1.add("item2");
hashList1.add("item3");
hashMap.put("key1", hashList1);
List<String> hashList2 = new ArrayList<>();
hashList2.add("item4");
hashList2.add("item5");
hashMap.put("key2", hashList2);
return hashMap;
}
}今回のテストクラスの内容は以下の通りで、MockMvcを利用して、コントローラクラスの各メソッドの動作を検証する内容になっている。
package com.example.demo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpSession;
import static org.junit.Assert.assertNull;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class DemoControllerTest {
/**
* MockMvcオブジェクト
*/
private MockMvc mockMvc;
/**
* テスト対象クラス
*/
@Autowired
DemoController target;
/**
* 前処理(各テストケースを実行する前に行われる処理)
*/
@Before
public void setup() {
// MockMvcオブジェクトにテスト対象メソッドを設定
mockMvc = MockMvcBuilders.standaloneSetup(target).build();
}
/**
* DemoControllerクラスのindexメソッドを確認するためのテスト
*/
@Test
public void indexTest() throws Exception{
// テスト対象メソッド(index)を実行
mockMvc.perform(get("/"))
// HTTPステータスがOKであることを確認
.andExpect(status().isOk())
// 次画面の遷移先がindex.htmlであることを確認
.andExpect(view().name("index"))
// セッションに設定されたsesHashMapの値が正しいことを確認
.andExpect(request().sessionAttribute("sesHashMap", createHashMap()))
// Modelオブジェクトにエラーが無いことを確認
.andExpect(model().hasNoErrors());
}
/**
* DemoControllerクラスのnextメソッドを確認するためのテスト
*/
@Test
public void nextTest() throws Exception {
HashMap<String, List<String>> paramMap = createHashMap();
// テスト対象メソッド(next)を実行
MvcResult results = mockMvc.perform(
// セッションsesHashMapを設定し、nextメソッドを実行
post("/next/").sessionAttr("sesHashMap", paramMap))
// HTTPステータスがOKであることを確認
.andExpect(status().isOk())
// 次画面の遷移先がnext.htmlであることを確認
.andExpect(view().name("next"))
// ModelオブジェクトのsessionListに設定される値が正しいことを確認
.andExpect(model().attribute("sessionList", paramMap.get("key1")))
// Modelオブジェクトにエラーが無いことを確認
.andExpect(model().hasNoErrors())
.andReturn();
// テスト対象メソッド(next)実施後のリクエストオブジェクトから、セッションを
// 取得し、セッションが取得できないことを確認
MockHttpServletRequest returnReq = results.getRequest();
HttpSession afterSession = returnReq.getSession(false);
assertNull(afterSession);
}
/**
* セッションに設定するハッシュマップを生成する
* @return 生成したハッシュマップ
*/
private HashMap<String, List<String>> createHashMap(){
HashMap<String, List<String>> hashMap = new HashMap<>();
List<String> hashList1 = new ArrayList<>();
hashList1.add("item1");
hashList1.add("item2");
hashList1.add("item3");
hashMap.put("key1", hashList1);
List<String> hashList2 = new ArrayList<>();
hashList2.add("item4");
hashList2.add("item5");
hashMap.put("key2", hashList2);
return hashMap;
}
}サラリーマン型フリーランスSEという働き方でお金の不安を解消しよう先日、「サラリーマン型フリーランスSE」という働き方を紹介するYouTube動画を視聴しましたので、その内容をご紹介します。 「サ...
サンプルプログラムの実行結果
JUnitテストクラスの実行結果は以下の通りで、テストが正常に実行されていることが確認できる。


要点まとめ
- MockMvcを利用すると、Spring MVCの動作を再現できるため、コントローラクラスのテストを行うことができる。
- MockMvcのperformメソッドでコントローラクラスのメソッドを実行でき、andExpectメソッドでコントローラクラスの動作検証が行える。





