SpringBootテスト備忘:@AutowiredしたオブジェクトでNullPointerExceptionが発生する場合の対応

Pocket

絶対後で忘れるので、備忘のため投稿。

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]

広告

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です