はじめに
コントローラテストについて、何を確認しているのか、どうやって書くのかを理解するために記事を書いていければと思います!
Controllerクラスでは何のテストをする?
Controllerクラスでは何のテストをするのか、どのような状態になればOKなのかについて理解していきます。
1.HTTPリクエストとレスポンスの確認
Controllerが正しいHTTPリクエストを受け取り、期待されるレスポンス(ステータスコードなど)を返すかどうかをテストします。
2.ルーティングの確認
各メソッドが正しいURLにマッピングされているかをテストします。
たとえば、@GetMapping, @PostMapping などのアノテーションが正しく設定されているかどうかを確認します。
3.サービス呼び出しの確認
Controllerがサービスを適切に呼びだせているかを確認します。
期待される引数がサービスに渡されて、サービスからの結果を正しく受け取れているかを確認します。
4.例外処理の確認
コントローラが特定の例外を処理しているかを確認します。
サービス層で例外が発生した場合にコントローラが適切なエラーレスポンスを返すかを確認します。
5.リクエストパラメータのバリデーション
リクエストパラメータやリクエストボディが正しくバリデーションされているかを確認します。
不正なデータが送信され時に適切なエラーメッセージやステータスコードが返されるかを確認します。
6.レスポンスの内容確認
コントローラーが正しい形式(例えばJSONやXML)でデータを返しているか、またその内容が期待通りであるかを確認します。
7.ヘッダーの確認
HTTPヘッダーが正しく設定されているかを確認します。
8.リダイレクトの確認
コントローラが適切にリダイレクトを行っているかを確認します。
Controllerクラステストの簡単な例
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/hotels")
public class HotelController {
@GetMapping("/info")
public String getHotelInfo(String id, Model model) {
model.addAttribute("id", id);
return "hotelInfo";
}
}
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@SpringBootTest
public class HotelControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetHotelInfo() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/hotels/info")
.param("id", "123")) ...1⃣
.andExpect(MockMvcResultMatchers.status().isOk()) ...2⃣
.andExpect(MockMvcResultMatchers.view().name("hotelInfo")) ...3⃣
.andExpect(MockMvcResultMatchers.model().attribute("message", "Hotel info for id: 123")); ...4⃣
}
@Test
public void testGetHotelInfo_NoId() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/hotels/info"))
.andExpect(MockMvcResultMatchers.status().is4xxClientError()); // IDパラメータなしのため、エラーを期待
}
}
【解説】
- MockMvcとは:コントローラーテストをするためのサポートツールでMockMvcを使用すると実際にサーバーを立ち上げることなくHTTPリクエストとレスポンスの処理をシミュレーションしてテストすることができる
< HTTPリクエストとレスポンスの確認 >
1⃣:/hotels/info エンドポイントへのGETリクエストを送信し、id パラメータに 123 を設定
2⃣:レスポンスのステータスコードが 200 OK であることを確認
< レスポンスの内容確認 >
3⃣:コントローラーが返すビューの名前が hotelInfo であることを確認
4⃣:モデルに含まれる属性 id の値が 123 であることを確認
testGetHotelInfo_NoId()では、パラメータを設定していません。
このメソッドではパラメータなしのリクエストに対してエラーが発生することを確認しています。
具体的には、4xx エラーステータスが返されることを期待しています。
さいごに
以上が、簡単なJUnitコントローラーテストについての説明ですが、1つずつかみ砕いて理解していくとあまり噛めることはない気がしました。
テストコードを書くことが少ないので、量をこなして慣れていきたいです。