Spring 3.2 Rundown, Miscellaneous

So, in this final part of my excursion into new Spring territory, I’ll talk about a few trends and tools noted in the “3.2 era”. This blog post will go high and low while trying to follow a red line, let’s see how it goes!

First of all, let’s take a look at some of the tools that leverage the ongoing boom in REST-ful API:s.

Spring HATEOAS is a framework helping out with writing HATEOAS compliant REST-interfaces (which is really a fundamental principle of REST!). Basically, a client should only take actions on a resource that were described in representations previously received from the server. You could say that the client should be able to be agnostic in terms of what resources are available, and how they are linked. So, not surprisingly, this Spring framework has support for adding this type of information to the representations the server sends back to the client. It can help you keep track of how to create the necessary relative links to other resources in your application. I believe this principle of REST is pretty fantastic, yet not fully leveraged by many teams, and I encourage you to take look!

Spring REST-shell is a tool used to help REST developers test and explore their interfaces. The command line-style shell have several commands and features such as discovering resources, following paths within the interface, setting the HTTP request headers and posting JSON (although that is somewhat clunky). An intended use of this shell is together with the HATEOAS framework, fully leveraging HATEOAS-style links. An example would be that a resource which has a “rel” linking to another resource, can easily be followed via commands instead of having to manipulate the resource URL.

The above tools can actually be used together with Spring Data Rest to, with very little boilerplate code, create a HATEOAS compliant REST-interface on top of your model.

Finally, a small reflection that most of the Spring projects on Github now seem to use Gradle instead of Maven. It’s not particularly new that Gradle is the new kid on the block, however you should take notice that things are happening here. Apparently, ThoughtWorks goes so far as to put Gradle in the ‘Adopt’ quadrant in their 2013 technology radar, whilst Maven falls back to ‘Hold’.

Spring 3.2 Rundown, Content Negotiation

Another one of the new Spring 3.2 features is better support for content negotiation. I’ll introduce the topic briefly here, and share some thoughts.

Content negotiation is used to indicate either what type of content a client would like to receive, or to indicate what type of content the server will return. This is useful for various reasons, some being:

  • Enabling servers to deliver content of the client’s preferred type.
  • Enabling better error handling, when there is a mis-match in client-server content types.
  • Serving content on the same location to different kinds of clients, such as browsers or mobile apps.

Anyway this is hardly news for anyone (!) and the technology is widely used, particularly in its most classic way, via HTTP headers. But with Spring 3.2, there are new features that help us with making the most out of a variety of content negotiation techniques:

  • URL path extension. E.g. ‘some/url/index.html’ versus ‘some/url/index.json’
  • URL path parameter. E.g. ‘some/url/index?format=html’
  • HTTP ‘Accept’ header

To minimize Internet waste, I’ve decided to not go more in depth here, and I will simply recommend that you take a look at this Spring blog which does a great job of explaining the topic. Or you can skip the reading and jump straight to the author’s demo!

Spring 3.2 Rundown, MVC Testing

Spring 3.2 comes with new, improved support for testing within the Spring MVC domain. The gist of the new MVC test feature, is that you can test your controllers in ways such that requests are routed via a proper MVC infrastructure, i.e. via the DispatcherServlet.
Previously, you may have used various mocks to test the code inside each controller method. With the new functionality, you can also test and verify specifics of the controller method, such as the mapping, HTTP headers, request data, content types and more.

So how would you accomplish this? Let’s start by turning our attention to the spring-test module, and the org.springframework.test.web.servlet package where we find the new MockMvc class. MockMvc acts as an entry point to the MVC structure under test. It’s a tool you can use to simulate requests against your controllers, with support for all kinds of assertions on the results. As indicated above, everything about your controller should work as it would at runtime, including servlet filters, view templates and the like. However, the requests will not be running in an actual servlet container, which means that JSPs will not work properly (although you can still assert some things like what model objects were set).

To get hold of an instance of MockMvc, there’s a convenient builder, namely org.springframerowk.test.web.servlet.setup.MockMvcBuilders. Currently, there are two builders you can instantiate, and they should be used for different purposes.

First, you can create a standalone MockMvc for one or more of your controller objects (annotated with @Controller). A “minimum” infrastructure required by the DispatcherServlet is then created, which may be customized as needed. This option is specifically intended for unit testing one controller at a time, leaving testing of the MVC infrastructure itself, the Web Application Context, to other test classes.

Second, you may create a MockMvc given a particular WebApplicationContext (a class which is also new in 3.2). This allows you to load a full Spring MVC configuration in which the controller under test will exist during tests. This option should be considered for integration tests, where the focus isn’t solely on the controller’s code, but the effective behaviour of the controller in the scope of the tested application.

Now it’s time to look at an example, which will demonstrate a standalone controller test and how to perform assertions. First, a very simple controller:

@Controller
public class BlogController {

    @RequestMapping(value = "/mvc/plaintext", method = RequestMethod.GET, headers = "Accept=text/plain")
    @ResponseBody
    public String plain() {
        return "a response body";
    }

}

And a simple test for this controller:

import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

public class BlogControllerTest {
    @Test
    public void testPlain() throws Exception {
        MockMvcBuilders.standaloneSetup(new BlogController()).build()
                .perform(get("/mvc/plaintext"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().contentType("text/plain"))
                .andExpect(content().string("a response body"));
    }
}

As you can see, MockMvc allows for a fluent-API way of testing the controller, including assertions.

When you call “perform” on MockMvc, the result is a ResultActions, on which you can “expect” a wide variety of criteria via the “andExpect” method. The criteria here, are instances of ResultMatcher, for which there exist a large number of helper classes. For example, MockMvcResultMatchers can be statically imported to support matchers for asserting content, view, model, urls, response status, headers and more!

As we saw, there’s also a static “print” method, used as parameter to “andDo” on the ResultActions object, which will dump the result of the performed request to standard out:

this.mockMvc.perform(......).andDo(print());

Hopefully, this blog is enough to get you going with MVC testing. If you want to go more in depth in this topic, take a look at the Spring blog, consult the reference manual, and check out the Spring MVC Showcase, which includes a large amount of samples of what is possible with the new MVC testing features. Also check out this Spring blog which discusses other new, general testing features such as how you can set up and customize mocked application contexts.

These great new features mean there’s really no excuse not to test controllers, so now we can finally stop starting web servers to find out whether our code works!