Spring Bootで単体テストを実装中、MockMvcを使ったテストを行いました。パラメータの受け渡しなどは実装できていたのですが、Sessionに値を設定した状態のテストをしようとした際に問題が発生。
今回のプロジェクトではSessionをデータベース(MySQL)を使って管理していました。セッション管理をデフォルトに戻すとちゃんとセッションに初期値を設定できるのですが、データベース管理だとどうしてもうまくいきません。
この記事ではSession管理にデータベースを使った際に、MockMvcを使ってうまくテストできるようにする方法を書いていきます。
結論:@AutoConfigureMockMvcは使わない
まず結論から書いていくと、MockMvcの初期化方法を手動で行う必要があります。@AutoConfigureMockMvcでの初期化ではだめでした。
うまくいくコードは以下の通りです。
@SpringBootTest
public class MockMvcTest {
private MockMvc mockMvc;
@Autowired
WebApplicationContext webApplicationContext;
@BeforeEach
void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
void testSession() throws Exception {
// @formatter:off
this.mockMvc.perform(get("/login").sessionAttr("input", "input"))
.andExpect(request().sessionAttribute("output", "output"))
.andExpect(request().sessionAttribute("input", "input"));
// @formatter:on
}
}
うまく行かなかった例
こちらがもともと書いていたコード。MockMvcを@AutoConfigureMockMvcで初期化して使っていました。この手法でも、Sessionをデフォルトのままアプリケーションサーバで管理している場合はうまくいくのですが、データベースで管理していると失敗します。
// DBでセッション管理しているとうまく行かない例
@SpringBootTest
@AutoConfigureMockMvc
public class MockMvcTest {
@Autowired
private MockMvc mockMvc;
@Test
void testSession() throws Exception{
// @formatter:off
this.mockMvc.perform(get("/login").sessionAttr("input", "input"))
// ここでエラー発生。SessionをControllerから受け取れない
.andExpect(request().sessionAttribute("output", "output"))
// こっちでもエラー。渡したはずのセッション情報がなくなった
.andExpect(request().sessionAttribute("input", "input"));
// @formatter:on
}
}
コメント