带有@RequestParam 和状态的@Controller 的WebMvcTest 不是200,而是400

WebMvcTest of @Controller with @RequestParam and status is not 200, but 400

我试着写@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);
    }

我的控制器:

@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";
    }

但它有失败:"Status expected:<200> but was:<400>" 这在控制台中:

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

我试过不使用.param("day", date.toString), 给这个参数设置多种格式的字符串,不使用.param,但是我有这个异常,你能帮忙吗我和它。其他方法的所有其他测试都成功,但这些方法中没有@RequestParam。那么我如何测试这样的方法

控制器缺少解析数据的逻辑。 Spring 默认情况下不知道如何将字符串转换为日期时间对象。有两种方法可以解决这个问题,一种解决方案可以将日期读取为字符串而不是 LocalDate,然后解析字符串以获取开始日期和结束日期,但是使用 @DateTimeFormat https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/format/annotation/DateTimeFormat.html

有更好的方法

控制器方法变成这样

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

测试 mockMvc 可以保留原样,因为您正在做 LocalDateTime.now().toString()