Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Spring Bootでコントローラの単体テスト

$
0
0

Spring Bootは単体テスト機能もついてます。

35. Testing

Spring Bootでコントローラの単体テストをするには、まず単体テストのクラスをアノテーションでいろいろ飾ってやる必要があります。

package okazuki.validationEdu;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration@ContextConfiguration(classes = App.class)
publicclass HomeControllerTest {


}

RunWithで実行をSpringのJUnitRunnerに切り替えて、Web系の設定をやるように指定して、最後にContextを設定します。ここでは本番用のAppクラスをそのまま指定していますが、テスト用の設定をしたクラスを指定してもOKです。

そして、コントローラのフィールドにモックを仕込みたい場合は、以下のようにMockitRuleというものをpublicなフィールドに用意します。

@Rulepublicfinal MockitoRule rule = MockitoJUnit.rule();

そして、テスト対象のコントローラとMockとして差し込みたいクラスをInjectMocksとMockアノテーションをつけて定義します。

@InjectMocksprivate HomeController controller;

    @Mockprivate Logic logic;

そして、MockMvcをフィールドに定義してBeforeで初期化します。

private MockMvc mockMvc;

    @Beforepublicvoid before() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(this.controller).build();
    }

あとはMockitoでモックの挙動を指定してmockMvcを使ってテストを書くだけです。

@Testpublicvoid test() throws Exception {
        Mockito.when(logic.greet()).thenReturn("こんにちは世界");
        
        this.mockMvc.perform(MockMvcRequestBuilders.post("/").param("name", ""))
            .andDo(MockMvcResultHandlers.print())
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andExpect(MockMvcResultMatchers.model().hasErrors())
            .andExpect(MockMvcResultMatchers.view().name("index"))
            .andExpect(MockMvcResultMatchers.model().attribute("message", "こんにちは世界"));
    }

むずいわ!

コードの全体はこんな感じです。

package okazuki.validationEdu;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration@ContextConfiguration(classes = App.class)
publicclass HomeControllerTest {

    @Rulepublicfinal MockitoRule rule = MockitoJUnit.rule();

    private MockMvc mockMvc;

    @InjectMocksprivate HomeController controller;

    @Mockprivate Logic logic;

    @Beforepublicvoid before() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(this.controller).build();
    }

    @Testpublicvoid test() throws Exception {
        Mockito.when(logic.greet()).thenReturn("こんにちは世界");
        
        this.mockMvc.perform(MockMvcRequestBuilders.post("/").param("name", ""))
            .andDo(MockMvcResultHandlers.print())
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andExpect(MockMvcResultMatchers.model().hasErrors())
            .andExpect(MockMvcResultMatchers.view().name("index"))
            .andExpect(MockMvcResultMatchers.model().attribute("message", "こんにちは世界"));
    }
}

テスト対象のコントローラはこんな感じ。

package okazuki.validationEdu;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controllerpublicclass HomeController {

    @Autowired
    Logic logic;
    
    @RequestMappingpublic String index(@ModelAttribute("form") Person p) {
        return"index";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String indexPost(@ModelAttribute("form") @Validated(All.class) Person p, BindingResult r, Model model) {
        model.addAttribute("message", this.logic.greet());
        return"index";
    }
}

Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>