絶対後で忘れるので、備忘のため投稿。
SpringBootでMockMvcを使ったテストを行っていた際、Controllerクラス内にある@AutowiredしたServiceクラスがNullPointerExceptionになりました。
最初はスタンドアロンでテストしていたので、以下のように記述していました。
public class 〇〇ControllerTest {
private MockMvc mockMvc;
@Before
public void before() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(new 〇〇Controller()).build();
}
@Test
public void てすと() throws Exception {
mockMvc.perform(post("/path")
.andExpect(status().isOk());
}
}
しかしServiceクラスやRepositoryクラスなど、@Autowiredを使った構成にしたところ上記のNullPointerExceptionが発生。
対応策は以下2点。
・サーバー起動でテストする
・@AutowiredでDIされるクラスを呼び出す、MockMvc自体もDIする
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class 〇〇ControllerTest {
@Autowired
private MockMvc mockMvc;
@Before
public void before() throws Exception {
// mockMvc = MockMvcBuilders.standaloneSetup(new 〇〇Controller()).build();
}
@Test
public void てすと() throws Exception {
mockMvc.perform(post("/path")
.andExpect(status().isOk());
}
}
うーん、DI慣れてないから。。。
【追記(2019/6/21)】
以下2点、備忘のため記録。
①tymeleafの循環ビューエラー
tymeleafを使用している場合、MockMVCはHTMLファイルテンプレートの場所やページファイルの拡張子が.htmlであることを理解してくれないようです。そのため、循環ビューが発生しているなどのエラーが吐かれます。
明示的にコンテキスト(WEBアプリの状況)を設定してあげれば解決します。
例)
@Autowired
WebApplicationContext wac;
@Before
public void before() throws Exception {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/templates");
viewResolver.setSuffix(".html");
StudentLearnController()).setViewResolvers(viewResolver).build();
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
②MockMVCの動作オプション
MockMVCは以下2つの動作オプションを持っています。
(1)webAppContextSetup
(2)standaloneSetup
私はとりあえずテストを厳密にする予定がないのでwebAppContextSetupを使用していますが、こちらは通常起動した時と同じような挙動でテストが行えます。
standaloneSetupを使用する場合はControllerクラス内でDIしているコンポーネントに色々設定が必要な様子。今のところwebAppContextSetupを使えばいいという状況ですが、いずれstandaloneSetupを使う必要性がでてきたら、改めて調べる予定で。。。
※参考URL10.2.4. 単体テストで利用するOSSライブラリの使い方 — TERASOLUNA
[/bash]
