Close

Spring MVC - Unit Testing PATCH Requests

[Last Updated: Feb 24, 2018]

This tutorial shows how to use Spring unit testing API and mock objects to test controllers which handle PATCH requests.

Example

The controller

@Controller
@RequestMapping("/articles")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    //for xml and json
    @PatchMapping("/{id}")
    @ResponseBody
    public String patchArticle(@RequestBody Article article) {
        System.out.println("Article updating in controller: " + article);
        articleService.updateArticle(article.getId(), article.getContent());
        return "Article updated with content: " + article.getContent();
    }

    //for x-www-form-urlencoded
    @PatchMapping(value = "/{id}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public String patchArticle(@RequestBody MultiValueMap<String, String> formParams) {
        System.out.println(formParams);
        long id = Long.parseLong(formParams.getFirst("id"));
        String content = formParams.getFirst("content");
        articleService.updateArticle(id, content);
        return "Article updated with content: " + content;
    }
}
@XmlRootElement
public class Article {
    private long id;
    private String content;

    public Article() {
    }

    public Article(int id, String content) {
        this.id = id;
        this.content = content;
    }
    .............
}

Java Config

@EnableWebMvc
@Configuration
@ComponentScan
public class MyWebConfig implements WebMvcConfigurer {
}

Unit Tests

Let's create and run our tests for XML, JSON and x-www-form-urlencoded requests one by one.

Testing XML PATCH request

Running test ControllerPatchTests.testXmlController() from the IDE:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class ControllerPatchTests {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mockMvc;
    .............
    @Test
    public void testXmlController() throws Exception {
        long id = 1;
        String content = "new updated content";
        MockHttpServletRequestBuilder builder =
                MockMvcRequestBuilders.patch("/articles/" + id)
                                      .contentType(MediaType.APPLICATION_XML_VALUE)
                                      .accept(MediaType.APPLICATION_XML)
                                      .characterEncoding("UTF-8")
                                      .content(getArticleInXml(1, content));
        this.mockMvc.perform(builder)
                    .andExpect(MockMvcResultMatchers.status()
                                                    .isOk())
                    .andExpect(MockMvcResultMatchers.content()
                                                    .string("Article updated with content: " + content))
                    .andDo(MockMvcResultHandlers.print());
    }
    .............
    private String getArticleInXml(long id, String content) {
        return "<article><id>" + id + "</id><content>" + content + "</content></article>";
    }
}

Article updating in controller: Article{id=1, content='new updated content'}

MockHttpServletRequest:
HTTP Method = PATCH
Request URI = /articles/1
Parameters = {}
Headers = {Content-Type=[application/xml;charset=UTF-8], Accept=[application/xml]}
Body = <article><id>1</id><content>new updated content</content></article>
Session Attrs = {}

Handler:
Type = com.logicbig.example.ArticleController
Method = public java.lang.String com.logicbig.example.ArticleController.patchArticle(com.logicbig.example.Article)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/xml;charset=ISO-8859-1], Content-Length=[49]}
Content type = application/xml;charset=ISO-8859-1
Body = Article updated with content: new updated content
Forwarded URL = null
Redirected URL = null
Cookies = []

Testing JSON PATCH request

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class ControllerPatchTests {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mockMvc;
    .............
    @Test
    public void testJsonController() throws Exception {
        long id = 1;
        String content = "new updated content";
        MockHttpServletRequestBuilder builder =
                MockMvcRequestBuilders.patch("/articles/" + id)
                                      .contentType(MediaType.APPLICATION_JSON_VALUE)
                                      .accept(MediaType.APPLICATION_JSON)
                                      .characterEncoding("UTF-8")
                                      .content(getArticleInJson(1, content));
        this.mockMvc.perform(builder)
                    .andExpect(MockMvcResultMatchers.status()
                                                    .isOk())
                    .andExpect(MockMvcResultMatchers.content()
                                                    .string("Article updated with content: " + content))
                    .andDo(MockMvcResultHandlers.print());
    }
    .............
    private String getArticleInJson(long id, String content) {
        return "{\"id\":\"" + id + "\", \"content\":\"" + content + "\"}";
    }
    .............
}

Article updating in controller: Article{id=1, content='new updated content'}

MockHttpServletRequest:
HTTP Method = PATCH
Request URI = /articles/1
Parameters = {}
Headers = {Content-Type=[application/json;charset=UTF-8], Accept=[application/json]}
Body = {"id":"1", "content":"new updated content"}
Session Attrs = {}

Handler:
Type = com.logicbig.example.ArticleController
Method = public java.lang.String com.logicbig.example.ArticleController.patchArticle(com.logicbig.example.Article)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=ISO-8859-1], Content-Length=[49]}
Content type = application/json;charset=ISO-8859-1
Body = Article updated with content: new updated content
Forwarded URL = null
Redirected URL = null
Cookies = []

Testing x-www-form-urlencoded PATCH request

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = MyWebConfig.class)
public class ControllerPatchTests {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mockMvc;
    .............
    @Test
    public void testFormParamController() throws Exception {
        String id = "1";
        String content = "new updated content";
        MockHttpServletRequestBuilder builder =
                MockMvcRequestBuilders.patch("/articles/" + id)
                                      .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                                      .accept(MediaType.APPLICATION_FORM_URLENCODED)
                                      .characterEncoding("UTF-8")
                                      .content("id=" + id + "&content=" + content);
        this.mockMvc.perform(builder)
                    .andExpect(MockMvcResultMatchers.status()
                                                    .isOk())
                    .andExpect(MockMvcResultMatchers.content()
                                                    .string("Article updated with content: " + content))
                    .andDo(MockMvcResultHandlers.print());
    }
    .............
}

{id=[1], content=[new updated content]}

MockHttpServletRequest:
HTTP Method = PATCH
Request URI = /articles/1
Parameters = {id=[1], content=[new updated content]}
Headers = {Content-Type=[application/x-www-form-urlencoded;charset=UTF-8], Accept=[application/x-www-form-urlencoded]}
Body = id=1&content=new updated content
Session Attrs = {}

Handler:
Type = com.logicbig.example.ArticleController

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/x-www-form-urlencoded;charset=ISO-8859-1], Content-Length=[49]}
Content type = application/x-www-form-urlencoded;charset=ISO-8859-1
Body = Article updated with content: new updated content
Forwarded URL = null
Redirected URL = null
Cookies = []

Example Project

Dependencies and Technologies Used:

  • spring-webmvc 5.0.3.RELEASE: Spring Web MVC.
  • jackson-databind 2.9.4: General data-binding functionality for Jackson: works on core streaming API.
  • spring-test 5.0.3.RELEASE: Spring TestContext Framework.
  • junit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • javax.servlet-api 3.0.1 Java Servlet API
  • JDK 1.8
  • Maven 3.3.9

Spring Http Patch Unit Testing Example Select All Download
  • spring-patch-unit-testing-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
      • test
        • java
          • com
            • logicbig
              • example
                • ControllerPatchTests.java

    See Also