I decided to write a unit test with spring boot2, so I will organize the writing style.
How do you write a test of the value set in Model? I hope you can use it to remember in such cases.
Sample code is available on GitHub.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
this.mockMvc.perform(get("/")).andDo(print())
        //Whether to return the status "200 OK"
        .andExpect(status().isOk())
        .andExpect(status().is(200))
The documentation looks like here.
Both isOk () and is (200) give the same result.
@Controller
@EnableAutoConfiguration
public class HomeController {
  @GetMapping(path = "/")
  String home(HttpServletRequest request, Model model) {
    // home.Specify html
    return "home";
  }
}
With that feeling, you will return the thymeleaf template file. This is a test.
    //test
    this.mockMvc.perform(get("/")).andDo(print())
        //Whether to return the template "home"
        .andExpect(view().name("home"))
Test with the name method. The documentation is here.
You pack data into the Model with the controller, right?
MyData.java
public class MyData {
  private String strData;
  private int intData;
  public MyData(String strData, int intData) {
    this.strData = strData;
    this.intData = intData;
  }
  public void setStrData(String strData) {
    this.strData = strData;
  }
  public String getStrData() {
    return this.strData;
  }
  public void setIntData(int intData) {
    this.intData = intData;
  }
  public int getIntData() {
    return this.intData;
  }
}
HomeController.java
@Controller
@EnableAutoConfiguration
public class HomeController {
  @GetMapping(path = "/")
  String home(HttpServletRequest request, Model model) {
    // string
    model.addAttribute("test", "this is test");
    // HashMap<String, String>
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", "momotaro");
    map.put("age", "23");
    model.addAttribute("map", map);
    // List<String>
    List<String> list = new ArrayList<String>();
    list.add("list1");
    list.add("list2");
    list.add("list3");
    model.addAttribute("list", list);
    // List<MyData>
    List<MyData> list2 = new ArrayList<MyData>();
    list2.add(new MyData("test1", 111));
    list2.add(new MyData("test2", 222));
    model.addAttribute("list2", list2);
    // home.Specify html
    return "home";
  }
}
HomeControllerTest.java
@SpringBootTest(classes = HomeController.class)
@AutoConfigureMockMvc
public class HomeControllerTest {
  @Autowired
  private MockMvc mockMvc;
  @Test
void home screen() throws Exception {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", "momotaro");
    map.put("age", "23");
    List<String> list = new ArrayList<String>();
    list.add("list1");
    list.add("list2");
    list.add("list3");
    List<MyData> list2 = new ArrayList<MyData>();
    list2.add(new MyData("test1", 111));
    list2.add(new MyData("test2", 222));
    //test
    this.mockMvc.perform(get("/")).andDo(print())
        //Whether to return the status "200 OK"
        .andExpect(status().isOk())
        .andExpect(status().is(200))
        //Whether to return the template "home"
        .andExpect(view().name("home"))
        //Model test.
        //string type
        .andExpect(model().attribute("test", "this is test"))
        //HashMap type
        .andExpect(model().attribute("map", map))
        // List<String>Mold
        .andExpect(model().attribute("list", hasSize(3)))   //List size
        .andExpect(model().attribute("list", hasItem("list1")))   //Does list1 included
        .andExpect(model().attribute("list", hasItem("list2")))   //Does list2 included
        .andExpect(model().attribute("list", hasItem("list3")))   //Does list3 included
        .andExpect(model().attribute("list", contains("list1", "list2", "list3")))  // list1, list2,Is it included in the order of list3?
        .andExpect(model().attribute("list", is(list)))  //Whether it matches list
        // List<MyData>Mold
        .andExpect(model().attribute("list2", hasSize(2)))   //List size
        .andExpect(model().attribute("list2",
          hasItem(allOf(hasProperty("strData", is("test1")), hasProperty("intData", is(111))))
        ))   //Does this combination of data be included?
        .andExpect(model().attribute("list2",
          hasItem(allOf(hasProperty("strData", is("test2")), hasProperty("intData", is(222))))
        ))   //Does this combination of data be included?
        //.andExpect(model().attribute("list2", is(list2)))  //Whether it matches list2->This way of writing is not possible. An error will occur.
        ;
  }
}
You can test with the attribute method like this. The documentation is here
It will be redirected by POST processing.
HomeController.java
  @PostMapping(path = "/testpost")
  public ModelAndView testpost(RedirectAttributes redirectAttributes,  @RequestParam(value = "intvalue", required = false, defaultValue = "0") Integer intvalue) {
    ModelAndView modelAndView = new ModelAndView("redirect:/testget");
    //Check input value
    if (intvalue <= 0) {
      redirectAttributes.addFlashAttribute("error", "intvalue must be greater than 0");
      return modelAndView;
    }
    //Set data
    modelAndView.addObject("value", intvalue);
    return modelAndView;
  }
HomeControllerTest.java
  @Test
  void testpost() throws Exception {
    //If you do not pass the parameter, it will be caught in the check
    this.mockMvc.perform(post("/testpost")).andExpect(redirectedUrl("/testget"))
        .andExpect(flash().attribute("error", "intvalue must be greater than 0"));
    //Pass the check after passing the parameters
    this.mockMvc.perform(post("/testpost").param("intvalue", "5"))
        .andExpect(redirectedUrl("/testget?value=5"));
  }
Use redirectedUrl () to test the redirected URL.
Use flash () to test redirectAttributes.addFlashAttribute ().
Parameters received by POST can be specified by param ().
When receiving POST on Controller I think I'll do something about it. That test.
Here, DI a specific Service to Controller Let's test that the Servcie method is called in the Post process.
MyService.java
@Service
public class MyService {
  public void test(int value) {
    System.out.println("MyService.test()..." + value);
  }
}
HomeController.java
@Controller
@EnableAutoConfiguration
public class HomeController {
  @Autowired
  MyService myService;
  @PostMapping(path = "/testpost2")
  public String testpost2(@RequestParam(value = "intvalue", required = false, defaultValue = "0") Integer intvalue) {
    //MyService test()Call
    myService.test(intvalue);
    return "redirect:/";
  }
}
HomeControllerTest.java
@SpringBootTest(classes = HomeController.class)
@AutoConfigureMockMvc
public class HomeControllerTest {
  @Autowired
  private MockMvc mockMvc;
  @MockBean
  private MyService myService;
  @Test
  void testpos2() throws Exception {
    //redirectUrl check
    this.mockMvc.perform(post("/testpost2").param("intvalue", "5")).andExpect(redirectedUrl("/"));
    //MyService test()Test if the method was called with an argument value of 5
    verify(this.myService, times(1)).test(5);
  }
}
verify(this.myService, times(1)).test(5);
If you write "The test method of the MyService class was called once with an argument value of 5" It will be a test.
The test to see if it was called twice
verify(this.myService, times(2)).test(5);
And
When you want the argument value to be 10
verify(this.myService, times(1)).test(10);
Write.
by this, The controller test Checking the value of the parameter to isolate the process, Passing parameter values to functions of other services I think it can be narrowed down to two types.
Post parameters were specified in params (), The Get parameter is specified by the URL.
HomeController.java
  @GetMapping(path = "/testget")
  String testget(@RequestParam(value = "value", required = false, defaultValue = "0") Integer value, @ModelAttribute("error") String error, Model model) {
    model.addAttribute("strError", error);
    model.addAttribute("intValue", value);
    // testget.Specify html
    return "testget";
  }
HomeControllerTest.java
  @Test
  void testget() throws Exception {
    this.mockMvc.perform(get("/testget?value=5&error=SuperError")).andDo(print())
        //Whether to return the status "200 OK"
        .andExpect(status().isOk())
        //Whether to return the template "testget"
        .andExpect(view().name("testget"))
        //Model test.
        .andExpect(model().attribute("intValue", 5))
        .andExpect(model().attribute("strError", "SuperError"))
        ;
  }
It's still a memo when I started writing tests with spring boot, so I would like to continue to add more.
Sample code is available on GitHub.
end.
Recommended Posts