MockMvc
Test Get Method
Test case A (unit test)
VetController
@Controller
public class VetController {
private final ClinicService clinicService;
@Autowired
public VetController(ClinicService clinicService) {
this.clinicService = clinicService;
}
@RequestMapping(value = { "/vets.html"})
public String showVetList(Map model) {
// Here we are returning an object of type 'Vets' rather than a collection of Vet objects
// so it is simpler for Object-Xml mapping
Vets vets = new Vets();
vets.getVetList().addAll(this.clinicService.findVets());
model.put("vets", vets);
return "vets/vetList";
}
}
VetControllerTest
//...
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@ExtendWith(MockitoExtension.class)
class VetControllerTest {
@Mock
ClinicService clinicService;
@Mock
Map model;
@InjectMocks
VetController controller;
List vetsList = new ArrayList<>();
MockMvc mockMvc;
@BeforeEach
void setUp() {
vetsList.add(new Vet());
given(clinicService.findVets()).willReturn(vetsList);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
void testControllerShowVetList() throws Exception {
mockMvc.perform(get("/vets.html"))
.andExpect(status().isOk())
.andExpect(model().attributeExists("vets"))
.andExpect(view().name("vets/vetList"));
}
}
Test case B (integration test)
OwnerController
@Controller
public class OwnerController {
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
private final ClinicService clinicService;
@RequestMapping(value = "/owners/new", method = RequestMethod.GET)
public String initCreationForm(Map model) {
Owner owner = new Owner();
model.put("owner", owner);
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
}
}
OwnerControllerTest
// ...
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringJUnitWebConfig(locations = {"classpath:spring/mvc-test-config.xml",
"classpath:spring/mvc-core-config.xml"})
// @SpringJUnitWebConfig({Abc.class, Uvw.class})
class OwnerControllerTest {
@Autowired
OwnerController ownerController;
@Autowired
ClinicService clinicService;
MockMvc mockMvc;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(ownerController).build();
}
@Test
void initCreationFormTest() throws Exception {
mockMvc.perform(get("/owners/new"))
.andExpect(status().isOk())
.andExpect(model().attributeExists("owner"))
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
}
}
Test case C (integration test)
OwnerController
@Controller
public class OwnerController {
@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processFindForm(Owner owner, BindingResult result, Map model) {
// allow parameterless GET request for /owners to return all records
if (owner.getLastName() == null) {
owner.setLastName(""); // empty string signifies broadest possible search
}
// find owners by last name
Collection results = this.clinicService.findOwnerByLastName(owner.getLastName());
if (results.isEmpty()) {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
return "owners/findOwners";
} else if (results.size() == 1) {
// 1 owner found
owner = results.iterator().next();
return "redirect:/owners/" + owner.getId();
} else {
// multiple owners found
model.put("selections", results);
return "owners/ownersList";
}
}
}
OwnerControllerTest
// ...
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.reset;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
// Enable Mockito to run for the annotation processing, i.e., @Captor
@ExtendWith(MockitoExtension.class)
@SpringJUnitWebConfig(locations = {"classpath:spring/mvc-test-config.xml",
"classpath:spring/mvc-core-config.xml"})
class OwnerControllerTest {
@Autowired
OwnerController ownerController;
@Autowired
ClinicService clinicService;
MockMvc mockMvc;
// Enabled by @ExtendWith(MockitoExtension.class)
@Captor
ArgumentCaptor stringArgumentCaptor;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(ownerController).build();
}
// Mockito mock is managed by Spring context, the mock is getting reused
// and picked up mulitiple times between the tests
@AfterEach
void tearDown() {
reset(clinicService);
}
@Test
void testReturnListOfOwners() throws Exception {
given(clinicService.findOwnerByLastName("")).willReturn(Lists.newArrayList(new Owner(), new Owner()));
// Takes care of the section of
// else { model.put("selections", results);
// return "owners/ownersList"; }
mockMvc.perform(get("/owners"))
.andExpect(status().isOk())
.andExpect(view().name("owners/ownersList"));
// Takes care of the section of
// if (owner.getLastName() == null) { owner.setLastName(""); }
then(clinicService).should().findOwnerByLastName(stringArgumentCaptor.capture());
// Verifying that empty string is passed in using the stringArgumentCaptor
assertThat(stringArgumentCaptor.getValue()).isEqualToIgnoringCase("");
}
}
Test case D (integration test)
OwnerControllerTest
// Enable Mockito to run for the annotation processing, i.e., @Captor
@ExtendWith(MockitoExtension.class)
@SpringJUnitWebConfig(locations = {"classpath:spring/mvc-test-config.xml",
"classpath:spring/mvc-core-config.xml"})
class OwnerControllerTest {
@Autowired
OwnerController ownerController;
@Autowired
ClinicService clinicService;
MockMvc mockMvc;
@Captor
ArgumentCaptor stringArgumentCaptor;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(ownerController).build();
}
@AfterEach
void tearDown() {
reset(clinicService);
}
@Test
void testFindOwnerOneResult() throws Exception {
Owner justOne = new Owner();
justOne.setId(1);
final String findJustOne = "FindJustOne";
justOne.setLastName(findJustOne);
given(clinicService.findOwnerByLastName(findJustOne)).willReturn(Lists.newArrayList(justOne));
mockMvc.perform(get("/owners")
.param("lastName", findJustOne))
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/owners/1"));
then(clinicService).should().findOwnerByLastName(anyString());
}
}
Test Post Method
Test case E (integration test)
OwnerControllerTest
@ExtendWith(MockitoExtension.class)
@SpringJUnitWebConfig(locations = {"classpath:spring/mvc-test-config.xml",
"classpath:spring/mvc-core-config.xml"})
class OwnerControllerTest {
@Autowired
OwnerController ownerController;
@Autowired
ClinicService clinicService;
MockMvc mockMvc;
@Captor
ArgumentCaptor stringArgumentCaptor;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(ownerController).build();
}
@AfterEach
void tearDown() {
reset(clinicService);
}
@Test
void testNewOwnerPostValid() throws Exception {
mockMvc.perform(post("/owners/new")
.param("firstName", "Jimmy")
.param("lastName", "Buffett")
.param("address", "123 Duval St ")
.param("city", "Key West")
.param("telephone", "3151231234"))
.andExpect(status().is3xxRedirection());
}
@Test
void testNewOwnerPostNotValid() throws Exception {
mockMvc.perform(post("/owners/new")
.param("firstName", "Jimmy")
.param("lastName", "Buffett")
.param("city", "Key West"))
.andExpect(status().isOk())
.andExpect(model().attributeHasErrors("owner"))
.andExpect(model().attributeHasFieldErrors("owner", "address"))
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
}
}