i try to write @WebMvcTest:
@ExtendWith(SpringExtension.class)
@WebMvcTest(AudienceController.class)
class LectureControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private LectureService lectureService;
@MockBean
private GroupService groupService;
@MockBean
private TeacherService teacherService;
@MockBean
private StudentService studentService;
@BeforeEach
public void init() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new LectureController(lectureService, groupService, teacherService, studentService)).build();
}
@Test
void whenGetRequest_thenReturnTTForTeacherPage() throws Exception {
Teacher teacher = new Teacher(1, "teacher", "first");
Subject subject = new Subject(1, "first");
LocalDateTime date = LocalDateTime.now();
Audience audience = new Audience(1, 100);
Group group = new Group(1, "group");
Lecture lecture = new Lecture(1, teacher, subject, Arrays.asList(group), date);
lecture.setAudience(audience);
when(teacherService.findOne(1)).thenReturn(teacher);
when(lectureService.findLecturesByTeacher(teacher, date, date)).thenReturn(Arrays.asList(lecture));
mockMvc.perform(get("/lecture/TTForTeacher/{id}", 1)
.param("startDay", date.toString())
.param("endDay", date.toString()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(view().name("lecture/TTForTeacher"))
.andExpect(forwardedUrl("lecture/TTForTeacher"))
.andExpect(model().attribute("lectures", hasSize(1)))
.andExpect(model().attribute("lectures", hasItem(
allOf(
hasProperty("id", is(1)),
hasProperty("teacher", is(teacher)),
hasProperty("subject", is(subject)),
hasProperty("date", is(date)),
hasProperty("audience", is(audience)),
hasProperty("groups", is(Arrays.asList(group)))
)
)));
verify(lectureService, times(1)).findLecturesByTeacher(teacher, date, date);
}
for my controller:
@Controller
@RequestMapping("/lecture")
public class LectureController {
private LectureService lectureService;
private GroupService groupService;
private TeacherService teacherService;
private StudentService studentService;
public LectureController(LectureService lectureService, GroupService groupService, TeacherService teacherService,
StudentService studentService) {
this.lectureService = lectureService;
this.groupService = groupService;
this.teacherService = teacherService;
this.studentService = studentService;
}
@GetMapping("/TTForTeacher/{id}")
public String getTTForTeacher(@PathVariable("id") int id, @RequestParam(value = "startDay") LocalDateTime startDay,
@RequestParam(value = "endDay") LocalDateTime endDay, Model model) {
model.addAttribute("lectures",
lectureService.findLecturesByTeacher(teacherService.findOne(id), startDay, endDay));
return "lecture/TTForTeacher";
}
But it has failures: "Status expected:<200> but was:<400>" and this in console:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /lecture/TTForTeacher/1
Parameters = {startDay=[10.05.2020, 10:00], endDay=[31.05.2020, 20:00]}
Headers = []
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.foxminded.university.controller.LectureController
Method = com.foxminded.university.controller.LectureController#getTTForTeacher(int, LocalDateTime, LocalDateTime, Model)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.method.annotation.MethodArgumentTypeMismatchException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
I tried not use .param("day", date.toString), to set string of several formats to this param, to use not .param, but i have this exception, can u help me with it. All other test of other methods are successful, but there are no @RequestParam in those methods. So how can i test methods like this
The controller is missing logic to parse data. Spring by default does not know how to convert the string to datetime object. There are 2 ways of solving this, one solution could be read date as String instead of LocalDate and then parse String to get the startDay and endDay, but there is a better way using @DateTimeFormat https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/format/annotation/DateTimeFormat.html
Controller method becomes like this
public String getTTForTeacher(@PathVariable("id") int id, @RequestParam(value = "startDay") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDay,
@RequestParam(value = "endDay") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDay) {
Test mockMvc can be left as is since you are doing LocalDateTime.now().toString()