2

I have an endpoint like this:

@GetMapping("/path")
public ResponseDTO<Page<Program>> getProgramsByUserId(@PathVariable String userId,
                                                      Pageable pageable,
                                                      @RequestParam(required = false) LocalDate from,
                                                      @RequestParam(required = false) LocalDate to) {

    return null;
}

And spring property

spring:
  mvc:
    format:
      date: iso

for specifying date format for my request params. And I have a test for my controller:

@ExtendWith(MockitoExtension.class)
class Test {

    private MockMvc mockMvc;

    @InjectMocks
    private Controller controller;

    private final ObjectMapper objectMapper = new ObjectMapper();


    @BeforeEach
    void setUp() {
        objectMapper.registerModule(new JavaTimeModule());
        mockMvc = MockMvcBuilders
                .standaloneSetup(controller)
                .setControllerAdvice(new GlobalControllerAdvice())
                .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
                .build();
    }

    @Test
    void test() throws Exception {
        //given
        var pageable = PageRequest.of(0, 5);
        var from = LocalDate.of(2022, 1, 1);
        var to = LocalDate.of(2022, 12, 31);

        MvcResult mvcResult = mockMvc.perform(get("/path")
                        .param("page", pageable.getPageNumber() + "")
                        .param("size", pageable.getPageSize() + "")
                        .param("from", from.toString())
                        .param("to", to.toString()))
                .andExpect(status().isOk())
                .andReturn();
    }

}

where i build my mockMvc as standaloneSetup.

Problem: when I run my test it fails to convert date from string in format 2022-01-01 into LocalDate object, because this test doesn't use Spring properties and probably cannot, since I am using standaloneSetup

Question: how to configure my mockMvc to be able to convert string date into LocalDate object?

Note: I know, that I can use @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) annotation for my request param, but I want to do it globally via spring property.

eternal
  • 339
  • 2
  • 15

1 Answers1

1

This can be done by adding WebConversionService to mockMvc:

mockMvc = MockMvcBuilders
        .standaloneSetup(controller)
        .setConversionService(
                new WebConversionService(new DateTimeFormatters().dateFormat("iso"))
            )
        .setControllerAdvice(new GlobalControllerAdvice())
        .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
        .build();

Time and Date Time Format can be set similarly, refers to DateTimeFormatters

How to find this?

  1. I search for property spring.mvc.format.time in the library and see found spring-configuration-metadata.json
     {
       "name": "spring.mvc.format.date",
       "type": "java.lang.String",
       "description": "Date format to use, for example 'dd\/MM\/yyyy'.",
       "sourceType": "org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties$Format"
     },
    
  2. Then I check who is using WebMvcProperties$Format#getDate() and it leads me to WebMvcAutoConfiguration#mvcConversionService
     @Bean
     @Override
     public FormattingConversionService mvcConversionService() {
         Format format = this.mvcProperties.getFormat();
         WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()
                 .dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
         addFormatters(conversionService);
         return conversionService;
     }
    
samabcde
  • 6,988
  • 2
  • 25
  • 41