1

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

Jun K
  • 37
  • 1
  • 6

1 Answers1

2

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()

sushil
  • 1,576
  • 10
  • 14
  • thanks! it works! but it is very strange, cause when i run my application on server and try to get TT for teacher and to check if this controller work, all was fine and all works. why this could happend? but actually, thanks for help with this question – Jun K May 23 '20 at 11:45