Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I configure MockMvcBuilders.standaloneSetup() to use my message converter XML configuration?

I am developing a Spring MVC 3.2 web application and I am attempting to use the new MockMvc test utilities in my unit tests. I want to test both the individual controllers and that the entire web application loads my Spring configuration XML files. From the Javadoc, it looks like I want to use standaloneSetup for the former and webAppContextSetup for the latter.

However, I am running into a problem when my controller looks for message converters to convert output. My interpretation of the Javadoc for the standaloneSetup method does not seem to be correct. Here's the Javadoc for this method:

Build a MockMvc by registering one or more @Controller's instances and configuring Spring MVC infrastructure programmatically. This allows full control over the instantiation and initialization of controllers, and their dependencies, similar to plain unit tests while also making it possible to test one controller at a time.

When this option is used, the minimum infrastructure required by the DispatcherServlet to serve requests with annotated controllers is automatically created, and can be customized, resulting in configuration that is equivalent to what the MVC Java configuration provides except using builder style methods.

If the Spring MVC configuration of an application is relatively straight-forward, for example when using the MVC namespace or the MVC Java config, then using this builder might be a good option for testing a majority of controllers. A much smaller number of tests can be used to focus on testing and verifying the actual Spring MVC configuration.

I had interpreted "minimum infrastructure" and "and their dependencies" to mean that the controllers I specify would be loaded in addition to all of their dependencies, which I though included the message converters. However, this does not seem to be the case. I need a custom configuration for 2 requirements:

  1. A PUT operation which consumes "application/json" which is converted into a POJO with a Joda DateTime field. Because of this, I am including the following in my Spring configuration:

    <mvc:annotation-driven>
      <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper" ref="myObjectMapper" />
        </bean>
      </mvc:message-converters>
    </mvc:annotation-driven>
    

    This works fine with webAppContextSetup but if I want to use standaloneSetup it looks like I need to manually create and configure a MappingJackson2HttpMessageConverter configured with my custom ObjectMapper which registers the JodaModule.

    standaloneSetup(myController).setMessageConverters(myJsonConverter).build();
    
  2. A GET operation which produces "application/custom+xml". When I load webAppContextSetup, this works without additional configuration. However, when I load standaloneSetup, whatever Spring configuration that happened before is not happening and I see the following error message:

    org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    

    Can someone describe what is happening here? Are there some hidden or default message converters that are included when I call webAppContextSetup but when I call the above code am I overriding the those converters somehow? How can I include them?

Is there an easier way with MockMvc to setup a single controller and all of the configuration inside mvc:annotation-driven? Can I configure MockMvcBuilders.standaloneSetup() to use my message converter XML configuration instead of manually configuring each one?

like image 847
BennyMcBenBen Avatar asked Nov 24 '22 17:11

BennyMcBenBen


1 Answers

I don't think there is an easier way. You have to manually register each converter via StandaloneMockMvcBuilder#setMessageConverters. This makes sense because you are doing the same in your XML config. Note that it would be the same if using a Java @Configuration class.

The standalone setup is intended to load the least number of components as possible. It's what comes closest to a unit test in spring-test terms. If it's a unit test that you want, you should mock each dependency (including converters) of the controller you are going to test, using a mocking framework like Mockito.

You can find an example here (it's a didactic project written for university).

like image 130
Marco Ferrari Avatar answered Dec 21 '22 13:12

Marco Ferrari