Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-10167

Spring MVC Test Framework ignores custom formatter

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Invalid
    • Affects Version/s: 3.2 GA
    • Fix Version/s: None
    • Component/s: Web
    • Labels:
    • Last commented by a User:
      true

      Description

      Spring MVC Test Framework ignores custom formatter.

      Given following controller:

      @Controller
      public class SampleController {
      
          @RequestMapping(value = "/test", method = GET)
          @ResponseBody()
          public String test(SampleEnum sampleEnum) {
              return sampleEnum.toString();
          }
      }
      

      And following enum constant:

      public enum SampleEnum {
      
          VALUE1,
          VALUE2
      }
      

      And following entry in Java Spring configuration file extending from WebMvcConfigurationSupport:

      WebConfiguration.java
          @Override
          public void addFormatters(FormatterRegistry registry) {
              registry.removeConvertible(String.class, Enum.class);
              registry.addConverterFactory(new CustomEnumConverterFactory());
          }
      

      That uses custom enum formatter to allow using lowercase enum constants in requests parameters while continuing to use uppercase enum constants:

      public class CustomEnumConverterFactory implements ConverterFactory<String, Enum> {
      
          @SuppressWarnings("unchecked")
          public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
              return new StringToEnum(targetType);
          }
      
          private static class StringToEnum<T extends Enum> implements Converter<String, T> {
      
              private final Class<T> enumType;
      
              public StringToEnum(Class<T> enumType) {
                  this.enumType = enumType;
              }
      
              public T convert(String source) {
                  if (source.length() == 0) {
                      return null;
                  }
                  return (T) Enum.valueOf(this.enumType, source.toUpperCase().trim());
              }
          }
      }
      

      Then when running the container both requests below result in printing enum constant:

      http://localhost:8080/test?sampleEnum=VALUE1
      http://localhost:8080/test?sampleEnum=value1

      But when trying to verify that using MVC Test Framework the first test fails:

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes = {WebConfiguration.class})
      @WebAppConfiguration
      public class SampleControllerTest {
      
          private MockMvc mockMvc;
      
          @Before
          public void setUp() throws Exception {
              this.mockMvc = MockMvcBuilders.standaloneSetup(new SampleController()).build();
          }
      
          @Test
          public void shouldReturnSuccessfulResponseFromUpperCaseEnum() throws Exception {
              mockMvc.perform(get("/test?sampleEnum=VALUE1")).andExpect(status().isOk()).andExpect(content().string("VALUE1"));;
          }
      
          @Test
          public void shouldReturnSuccessfulResponseFromLowerCaseEnum() throws Exception {
              mockMvc.perform(get("/test?sampleEnum=value1")).andExpect(status().isOk()).andExpect(content().string("VALUE1"));
          }
      }
      

      The status returned in the first test when using MVC Test framework is 400 BAD REQUEST.

        Attachments

          Activity

            People

            Assignee:
            rstoya05-aop Rossen Stoyanchev
            Reporter:
            pioter Piotr Jagielski
            Last updater:
            Spring Issues Spring Issues
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Days since last comment:
              3 years, 1 week, 4 days ago