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>";
  }
}

Output


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 + "\"}";
  }
    .............
}

Output


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());
  }
    .............
}

Output


{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