{"id":16002,"date":"2013-08-07T13:00:03","date_gmt":"2013-08-07T10:00:03","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=16002"},"modified":"2013-08-06T21:00:02","modified_gmt":"2013-08-06T18:00:02","slug":"unit-testing-of-spring-mvc-controllers-rest-api","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html","title":{"rendered":"Unit Testing of Spring MVC Controllers: REST API"},"content":{"rendered":"<p>Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release of the <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/spring-framework-reference\/htmlsingle\/#spring-mvc-test-framework\" target=\"_blank\">Spring MVC Test framework<\/a> gave us the possibility to write unit tests which are readable, comprehensive and fast.<\/p>\n<p>This blog post describes how we can write unit tests for a REST API by using the Spring MVC Test framework. During this blog post we will write unit tests for controller methods which provide CRUD functions for todo entries.<\/p>\n<p>Let\u2019s get started.<br \/>\n&nbsp;<\/p>\n<h2>Getting The Required Dependencies with Maven<\/h2>\n<p>We can get the required testing dependencies by adding the following dependency declarations to our POM file:<\/p>\n<ul>\n<li>Hamcrest 1.3 (<em>hamcrest-all<\/em>). We use Hamcrest matchers when we are writing assertions for the responses.<\/li>\n<li>Junit 4.11. We need to exclude the <em>hamcrest-core<\/em> dependency because we already added the <em>hamcrest-all<\/em> dependency.<\/li>\n<li>Mockito 1.9.5 (<em>mockito-core<\/em>). We use Mockito as our mocking library.<\/li>\n<li>Spring Test 3.2.3.RELEASE<\/li>\n<li>JsonPath 0.8.1 (<em>json-path<\/em> and <em>json-path-assert<\/em>). We use JsonPath when we are writing assertions for JSON documents returned by our REST API.<\/li>\n<\/ul>\n<p>The relevant dependency declarations looks as follows:<\/p>\n<pre class=\"brush:xml\">&lt;dependency&gt;\r\n    &lt;groupId&gt;org.hamcrest&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;hamcrest-all&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.3&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;junit&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;junit&lt;\/artifactId&gt;\r\n    &lt;version&gt;4.11&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n    &lt;exclusions&gt;\r\n        &lt;exclusion&gt;\r\n            &lt;artifactId&gt;hamcrest-core&lt;\/artifactId&gt;\r\n            &lt;groupId&gt;org.hamcrest&lt;\/groupId&gt;\r\n        &lt;\/exclusion&gt;\r\n    &lt;\/exclusions&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.mockito&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;mockito-core&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.9.5&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;org.springframework&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;spring-test&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.2.3.RELEASE&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;com.jayway.jsonpath&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;json-path&lt;\/artifactId&gt;\r\n    &lt;version&gt;0.8.1&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;com.jayway.jsonpath&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;json-path-assert&lt;\/artifactId&gt;\r\n    &lt;version&gt;0.8.1&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n&lt;\/dependency&gt;<\/pre>\n<p>Let\u2019s move on and talk a bit about the configuration of our unit tests.<\/p>\n<h2>Configuring Our Unit Tests<\/h2>\n<p>The unit tests which we will write during this blog post use the web application context based configuration. This means that we configure the Spring MVC infrastructure by using either an application context configuration class or a XML configuration file.<\/p>\n<p>Because the <a href=\"http:\/\/www.petrikainulainen.net\/programming\/spring-framework\/unit-testing-of-spring-mvc-controllers-configuration#appcontext-config\">first part of this tutorial<\/a> described the principles which we should follow when we are configuring the application context of our application, this issue is not discussed in this blog post.<\/p>\n<p>However, there is one thing that we have to address here.<\/p>\n<p>The application context configuration class (or file) which configures the web layer of our example application does not create an exception resolver bean. The <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/portlet\/handler\/SimpleMappingExceptionResolver.html\" target=\"_blank\"><em>SimpleMappingExceptionResolver<\/em><\/a> class used in the earlier parts of this tutorial maps exception class name to the view which is rendered when the configured exception is thrown.<\/p>\n<p>This makes sense if we are implementing a \u201cnormal\u201d Spring MVC application. However, if we are implementing a REST API, we want to transform exceptions into HTTP status codes. This behavior is provided by the <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/servlet\/mvc\/annotation\/ResponseStatusExceptionResolver.html\" target=\"_blank\"><em>ResponseStatusExceptionResolver<\/em><\/a> class which is enabled by default.<\/p>\n<p>Our example application also has a <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/spring-framework-reference\/htmlsingle\/#mvc-exceptionhandlers-resolver\" target=\"_blank\">custom exception handler class which is annotated with the @ControllerAdvice annotation<\/a>. This class handles validation errors and application specific exceptions. We will talk more about this class later in this blog post.<\/p>\n<p>Let\u2019s move on and find out how we can write unit tests for our REST API.<\/p>\n<h2>Writing Unit Tests for a REST API<\/h2>\n<p>Before we can start writing unit tests for our REST API, we need to understand two things:<\/p>\n<ul>\n<li>We need to know what are the core components of the Spring MVC Test framework. These components are described in the <a href=\"http:\/\/www.petrikainulainen.net\/programming\/spring-framework\/unit-testing-of-spring-mvc-controllers-normal-controllers#writing-unit-tests\">second part of this tutorial<\/a>.<\/li>\n<li>We need to know how we can write assertions for JSON documents by using JsonPath expressions. We can get this information by reading my blog post which describes <a href=\"http:\/\/www.petrikainulainen.net\/programming\/spring-framework\/integration-testing-of-spring-mvc-applications-write-clean-assertions-with-jsonpath#writing-integration-tests\">how we can write clean assertions with JsonPath<\/a>.<\/li>\n<\/ul>\n<p>Next we will see the Spring MVC Test framework in action and write unit tests for the following controller methods:<\/p>\n<ul>\n<li>The first controller methods returns a list of todo entries.<\/li>\n<li>The second controller method returns the information of a single todo entry.<\/li>\n<li>The third controller method adds a new todo entry to the database and returns the added todo entry.<\/li>\n<\/ul>\n<h4>Get Todo Entries<\/h4>\n<p>The first controller method returns a list of todo entries which are found from the database. Let\u2019s start by taking a look at the implementation of this method.<\/p>\n<h2>Expected Behavior<\/h2>\n<p>The controller method which returns all todo entries stored to the database is implemented by following these steps:<\/p>\n<ol>\n<li>It processes <em>GET<\/em> requests send to url \u2018\/api\/todo\u2019.<\/li>\n<li>It gets a list of <em>Todo<\/em> objects by calling the <em>findAll()<\/em> method of the <em>TodoService<\/em> interface. This method returns all todo entries which are stored to the database. These todo entries are always returned in the same order.<\/li>\n<li>It transforms the received list into a list of <em>TodoDTO<\/em> objects.<\/li>\n<li>It returns the list which contains <em>TodoDTO<\/em> objects.<\/li>\n<\/ol>\n<p>The relevant part of the <em>TodoController<\/em> class looks as follows:<\/p>\n<pre class=\"brush:java\">import org.springframework.stereotype.Controller;\r\nimport org.springframework.web.bind.annotation.*;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n@Controller\r\npublic class TodoController {\r\n\r\n    private TodoService service;\r\n\r\n    @RequestMapping(value = \"\/api\/todo\", method = RequestMethod.GET)\r\n    @ResponseBody\r\n    public List&lt;TodoDTO&gt; findAll() {\r\n        List&lt;Todo&gt; models = service.findAll();\r\n        return createDTOs(models);\r\n    }\r\n\r\n    private List&lt;TodoDTO&gt; createDTOs(List&lt;Todo&gt; models) {\r\n        List&lt;TodoDTO&gt; dtos = new ArrayList&lt;&gt;();\r\n\r\n        for (Todo model: models) {\r\n            dtos.add(createDTO(model));\r\n        }\r\n\r\n        return dtos;\r\n    }\r\n\r\n    private TodoDTO createDTO(Todo model) {\r\n        TodoDTO dto = new TodoDTO();\r\n\r\n        dto.setId(model.getId());\r\n        dto.setDescription(model.getDescription());\r\n        dto.setTitle(model.getTitle());\r\n\r\n        return dto;\r\n    }\r\n}<\/pre>\n<p>When a list of <em>TodoDTO<\/em> objects is returned, Spring MVC transforms this list into a JSON document which contains a collection of objects. The returned JSON document looks as follows:<\/p>\n<pre class=\"brush:java\">[\r\n    {\r\n        \"id\":1,\r\n        \"description\":\"Lorem ipsum\",\r\n        \"title\":\"Foo\"\r\n    },\r\n    {\r\n        \"id\":2,\r\n        \"description\":\"Lorem ipsum\",\r\n        \"title\":\"Bar\"\r\n    }\r\n]<\/pre>\n<p>Let\u2019s move on and write an unit test which ensures that this controller method is working as expected.<\/p>\n<h2>Test: Todo Entries Are Found<\/h2>\n<p>We can write an unit test for this controller method by following these steps:<\/p>\n<ol>\n<li>Create the test data which is returned when the <em>findAll()<\/em> method of the <em>TodoService<\/em> interface is called. We create the test data by using a <a href=\"http:\/\/nat.truemesh.com\/archives\/000714.html\" target=\"_blank\">test data builder<\/a> class.<\/li>\n<li>Configure our mock object to return the created test data when its <em>findAll()<\/em> method is invoked.<\/li>\n<li>Execute a <em>GET<\/em> request to url \u2018\/api\/todo\u2019.<\/li>\n<li>Verify that the HTTP status code 200 is returned.<\/li>\n<li>Verify that the content type of the response is \u2018application\/json\u2019 and its character set is \u2018UTF-8\u2032.<\/li>\n<li>Get the collection of todo entries by using the JsonPath expression <em>$<\/em> and ensure that that two todo entries are returned.<\/li>\n<li>Get the <em>id<\/em>, <em>description<\/em>, and <em>title<\/em> of the first todo entry by using JsonPath expressions <em>$[0].id<\/em>, <em>$[0].description<\/em>, and <em>$[0].title<\/em>. Verify that the correct values are returned.<\/li>\n<li>Get the <em>id<\/em>, <em>description<\/em>, and title of the second todo entry by using JsonPath expressions <em>$[1].id<\/em>, <em>$[1].description<\/em>, and <em>$[1].title<\/em>. Verify that the correct values are returned.<\/li>\n<li>Verify that the <em>findAll()<\/em> method of the <em>TodoService<\/em> interface is called only once.<\/li>\n<li>Ensure that no other methods of our mock object are called during the test.<\/li>\n<\/ol>\n<p>The source code of our unit test looks as follows:<\/p>\n<pre class=\"brush:java\">import org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.test.context.ContextConfiguration;\r\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\r\nimport org.springframework.test.context.web.WebAppConfiguration;\r\nimport org.springframework.test.web.servlet.MockMvc;\r\n\r\nimport java.util.Arrays;\r\n\r\nimport static org.hamcrest.Matchers.*;\r\nimport static org.mockito.Mockito.*;\r\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\r\n\r\n@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(classes = {TestContext.class, WebAppContext.class})\r\n@WebAppConfiguration\r\npublic class TodoControllerTest {\r\n\r\n    private MockMvc mockMvc;\r\n\r\n    @Autowired\r\n    private TodoService todoServiceMock;\r\n\r\n    \/\/Add WebApplicationContext field here.\r\n\r\n    \/\/The setUp() method is omitted.\r\n\r\n    @Test\r\n    public void findAll_TodosFound_ShouldReturnFoundTodoEntries() throws Exception {\r\n        Todo first = new TodoBuilder()\r\n                .id(1L)\r\n                .description(\"Lorem ipsum\")\r\n                .title(\"Foo\")\r\n                .build();\r\n        Todo second = new TodoBuilder()\r\n                .id(2L)\r\n                .description(\"Lorem ipsum\")\r\n                .title(\"Bar\")\r\n                .build();\r\n\r\n        when(todoServiceMock.findAll()).thenReturn(Arrays.asList(first, second));\r\n\r\n        mockMvc.perform(get(\"\/api\/todo\"))\r\n                .andExpect(status().isOk())\r\n                .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))\r\n                .andExpect(jsonPath(\"$\", hasSize(2)))\r\n                .andExpect(jsonPath(\"$[0].id\", is(1)))\r\n                .andExpect(jsonPath(\"$[0].description\", is(\"Lorem ipsum\")))\r\n                .andExpect(jsonPath(\"$[0].title\", is(\"Foo\")))\r\n                .andExpect(jsonPath(\"$[1].id\", is(2)))\r\n                .andExpect(jsonPath(\"$[1].description\", is(\"Lorem ipsum\")))\r\n                .andExpect(jsonPath(\"$[1].title\", is(\"Bar\")));\r\n\r\n        verify(todoServiceMock, times(1)).findAll();\r\n        verifyNoMoreInteractions(todoServiceMock);\r\n    }\r\n}<\/pre>\n<p>Our unit test uses a constant called <em>APPLICATION_JSON_UTF8<\/em> which is declared in the <em>TestUtil<\/em> class. The value of that constant is a <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/http\/MediaType.html\" target=\"_blank\"><em>MediaType<\/em><\/a> object which content type is \u2018application\/json\u2019 and character set is \u2018UTF-8\u2032.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The relevant part of the <em>TestUtil<\/em> class looks as follows:<\/p>\n<pre class=\"brush:java\">public class TestUtil {\r\n\r\n    public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(),\r\nMediaType.APPLICATION_JSON.getSubtype(),                       \r\n    Charset.forName(\"utf8\")                    \r\n  );\r\n}<\/pre>\n<h4>Get Todo Entry<\/h4>\n<p>The second controller method which we have to test returns the information of a single todo entry. Let\u2019s find out how this controller method is implemented.<\/p>\n<h2>Expected Behavior<\/h2>\n<p>The controller method which returns the information of a single todo entry is implemented by following these steps:<\/p>\n<ol>\n<li>It processes <em>GET<\/em> requests send to url \u2018\/api\/todo\/{id}\u2019. The <em>{id}<\/em> is a path variable which contains the <em>id<\/em> of the requested todo entry.<\/li>\n<li>It obtains the requested todo entry by calling the <em>findById()<\/em> method of the <em>TodoService<\/em> interface and passes the <em>id<\/em> of the requested todo entry as a method parameter. This method returns the found todo entry. If no todo entry is found, this method throws a <em>TodoNotFoundException<\/em>.<\/li>\n<li>It transforms the <em>Todo<\/em> object into a <em>TodoDTO<\/em> object.<\/li>\n<li>It returns the created <em>TodoDTO<\/em> object.<\/li>\n<\/ol>\n<p>The source code of our controller method looks as follows:<\/p>\n<pre class=\"brush:java\">import org.springframework.stereotype.Controller;\r\nimport org.springframework.web.bind.annotation.*;\r\n\r\n@Controller\r\npublic class TodoController {\r\n\r\n    private TodoService service;\r\n\r\n    @RequestMapping(value = \"\/api\/todo\/{id}\", method = RequestMethod.GET)\r\n    @ResponseBody\r\n    public TodoDTO findById(@PathVariable(\"id\") Long id) throws TodoNotFoundException {\r\n        Todo found = service.findById(id);\r\n        return createDTO(found);\r\n    }\r\n\r\n    private TodoDTO createDTO(Todo model) {\r\n        TodoDTO dto = new TodoDTO();\r\n\r\n        dto.setId(model.getId());\r\n        dto.setDescription(model.getDescription());\r\n        dto.setTitle(model.getTitle());\r\n\r\n        return dto;\r\n    }\r\n}<\/pre>\n<p>The JSON document which is returned to the client looks as follows:<\/p>\n<pre class=\"brush:java\">{\r\n    \"id\":1,\r\n    \"description\":\"Lorem ipsum\",\r\n    \"title\":\"Foo\"\r\n}<\/pre>\n<p>Our next question is:<\/p>\n<blockquote>\n<p>What happens when a TodoNotFoundException is thrown?<\/p>\n<\/blockquote>\n<p>Our example application has an exception handler class which handles application specific exceptions thrown by our controller classes. This class has an exception handler method which is called when a <em>TodoNotFoundException<\/em> is thrown. The implementation of this method writes a new log message to the log file and ensures that the HTTP status code 404 is send back to the client.<\/p>\n<p>The relevant part of the <em>RestErrorHandler<\/em> class looks as follows:<\/p>\n<pre class=\"brush:java\">import org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.http.HttpStatus;\r\nimport org.springframework.web.bind.annotation.ControllerAdvice;\r\nimport org.springframework.web.bind.annotation.ExceptionHandler;\r\nimport org.springframework.web.bind.annotation.ResponseStatus;\r\n\r\n@ControllerAdvice\r\npublic class RestErrorHandler {\r\n\r\n    private static final Logger LOGGER = LoggerFactory.getLogger(RestErrorHandler.class);\r\n\r\n    @ExceptionHandler(TodoNotFoundException.class)\r\n    @ResponseStatus(HttpStatus.NOT_FOUND)\r\n    public void handleTodoNotFoundException(TodoNotFoundException ex) {\r\n        LOGGER.debug(\"handling 404 error on a todo entry\");\r\n    }\r\n}<\/pre>\n<p>We have to write two unit tests for this controller method:<\/p>\n<ol>\n<li>We have to write a test which ensures that our application is working properly when the todo entry is not found.<\/li>\n<li>We have to write a test which verifies that the correct data is returned to the client when the todo entry is found.<\/li>\n<\/ol>\n<p>Let\u2019s see how we can write these tests.<\/p>\n<h2>Test 1: Todo Entry Is Not Found<\/h2>\n<p>First, we must ensure that our application is working properly when a todo entry is not found. We can write an unit test which ensures this by following these steps:<\/p>\n<ol>\n<li>Configure our mock object to throw a <em>TodoNotFoundException<\/em> when its <em>findById()<\/em> method is called and the <em>id<\/em> of the requested todo entry is 1L.<\/li>\n<li>Execute a <em>GET<\/em> request to url \u2018\/api\/todo\/1\u2032.<\/li>\n<li>Verify that the HTTP status code 404 is returned.<\/li>\n<li>Ensure that the <em>findById()<\/em> method of the <em>TodoService<\/em> interface is called only once by using the correct method parameter (1L).<\/li>\n<li>Verify that no other methods of the <em>TodoService<\/em> interface are called during this test.<\/li>\n<\/ol>\n<p>The source code of our unit test looks as follows:<\/p>\n<pre class=\"brush:java\">import org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.test.context.ContextConfiguration;\r\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\r\nimport org.springframework.test.context.web.WebAppConfiguration;\r\nimport org.springframework.test.web.servlet.MockMvc;\r\n\r\nimport static org.mockito.Mockito.*;\r\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\r\n\r\n@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(classes = {TestContext.class, WebAppContext.class})\r\n@WebAppConfiguration\r\npublic class TodoControllerTest {\r\n\r\n    private MockMvc mockMvc;\r\n\r\n    @Autowired\r\n    private TodoService todoServiceMock;\r\n\r\n    \/\/Add WebApplicationContext field here.\r\n\r\n    \/\/The setUp() method is omitted.\r\n\r\n    @Test\r\n    public void findById_TodoEntryNotFound_ShouldReturnHttpStatusCode404() throws Exception {\r\n        when(todoServiceMock.findById(1L)).thenThrow(new TodoNotFoundException(\"\"));\r\n\r\n        mockMvc.perform(get(\"\/api\/todo\/{id}\", 1L))\r\n                .andExpect(status().isNotFound());\r\n\r\n        verify(todoServiceMock, times(1)).findById(1L);\r\n        verifyNoMoreInteractions(todoServiceMock);\r\n    }\r\n}<\/pre>\n<h2>Test 2: Todo Entry Is Found<\/h2>\n<p>Second, we must write a test which ensures that the correct data is returned when the requested todo entry is found. We can write a test which ensures this by following these steps:<\/p>\n<ol>\n<li>Create the <em>Todo<\/em> object which is returned when our service method is called. We create this object by using our test data builder.<\/li>\n<li>Configure our mock object to return the created <em>Todo<\/em> object when its <em>findById()<\/em> method is called by using a method parameter 1L.<\/li>\n<li>Execute a <em>GET<\/em> request to url \u2018\/api\/todo\/1\u2032.<\/li>\n<li>Verify that the HTTP status code 200 is returned.<\/li>\n<li>Verify that the content type of the response is \u2018application\/json\u2019 and its character set is \u2018UTF-8\u2032.<\/li>\n<li>Get the <em>id<\/em> of the todo entry by using the JsonPath expression <em>$.id<\/em> and verify that the <em>id<\/em> is 1.<\/li>\n<li>Get the <em>description<\/em> of the todo entry by using the JsonPath expression <em>$.description<\/em> and verify that the <em>description<\/em> is \u201cLorem ipsum\u201d.<\/li>\n<li>Get the <em>title<\/em> of the todo entry by using the JsonPath expression <em>$.title<\/em> and verify that the title is \u201cFoo\u201d.<\/li>\n<li>Ensure that the <em>findById()<\/em> method of the <em>TodoService<\/em> interface is called only once by using the correct method parameter (1L).<\/li>\n<li>Verify that the other methods of our mock object are not called during the test.<\/li>\n<\/ol>\n<p>The source code of our unit test looks as follows:<\/p>\n<pre class=\"brush:java\">import org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.test.context.ContextConfiguration;\r\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\r\nimport org.springframework.test.context.web.WebAppConfiguration;\r\nimport org.springframework.test.web.servlet.MockMvc;\r\n\r\nimport static org.hamcrest.Matchers.is;\r\nimport static org.mockito.Mockito.*;\r\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;\r\n\r\n@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(classes = {TestContext.class, WebAppContext.class})\r\n@WebAppConfiguration\r\npublic class TodoControllerTest {\r\n\r\n    private MockMvc mockMvc;\r\n\r\n    @Autowired\r\n    private TodoService todoServiceMock;\r\n\r\n    \/\/Add WebApplicationContext field here.\r\n\r\n    \/\/The setUp() method is omitted.\r\n\r\n    @Test\r\n    public void findById_TodoEntryFound_ShouldReturnFoundTodoEntry() throws Exception {\r\n        Todo found = new TodoBuilder()\r\n                .id(1L)\r\n                .description(\"Lorem ipsum\")\r\n                .title(\"Foo\")\r\n                .build();\r\n\r\n        when(todoServiceMock.findById(1L)).thenReturn(found);\r\n\r\n        mockMvc.perform(get(\"\/api\/todo\/{id}\", 1L))\r\n                .andExpect(status().isOk())\r\n                .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))\r\n                .andExpect(jsonPath(\"$.id\", is(1)))\r\n                .andExpect(jsonPath(\"$.description\", is(\"Lorem ipsum\")))\r\n                .andExpect(jsonPath(\"$.title\", is(\"Foo\")));\r\n\r\n        verify(todoServiceMock, times(1)).findById(1L);\r\n        verifyNoMoreInteractions(todoServiceMock);\r\n    }\r\n}<\/pre>\n<h4>Add New Todo Entry<\/h4>\n<p>The third controller method adds a new todo entry to the database and returns the information of the added todo entry. Let\u2019s move on and find out how it is implemented.<\/p>\n<h2>Expected Behavior<\/h2>\n<p>The controller method which adds new todo entries to the database is implemented by following these steps:<\/p>\n<ol>\n<li>It processes <em>POST<\/em> requests send to url \u2018\/api\/todo\u2019.<\/li>\n<li>It validates the <em>TodoDTO<\/em> object given as a method parameter. If the validation fails, a <a href=\"http:\/\/static.springsource.org\/spring\/docs\/3.2.x\/javadoc-api\/org\/springframework\/web\/bind\/MethodArgumentNotValidException.html\" target=\"_blank\"><em>MethodArgumentNotValidException<\/em><\/a> is thrown.<\/li>\n<li>It Adds a new todo entry to the database by calling the <em>add()<\/em> method of the <em>TodoService<\/em> interface and passes the <em>TodoDTO<\/em> object as a method parameter. This method adds a new todo entry to the database and returns the added todo entry.<\/li>\n<li>It transforms the created <em>Todo<\/em> object into a <em>TodoDTO<\/em> object.<\/li>\n<li>It returns the <em>TodoDTO<\/em> object.<\/li>\n<\/ol>\n<p>The source code of our controller method looks as follows:<\/p>\n<pre class=\"brush:java\">import org.springframework.stereotype.Controller;\r\nimport org.springframework.web.bind.annotation.*;\r\n\r\nimport javax.validation.Valid;\r\n\r\n@Controller\r\npublic class TodoController {\r\n\r\n    private TodoService service;\r\n\r\n    @RequestMapping(value = \"\/api\/todo\", method = RequestMethod.POST)\r\n    @ResponseBody\r\n    public TodoDTO add(@Valid @RequestBody TodoDTO dto) {\r\n        Todo added = service.add(dto);\r\n        return createDTO(added);\r\n    }\r\n\r\n    private TodoDTO createDTO(Todo model) {\r\n        TodoDTO dto = new TodoDTO();\r\n\r\n        dto.setId(model.getId());\r\n        dto.setDescription(model.getDescription());\r\n        dto.setTitle(model.getTitle());\r\n\r\n        return dto;\r\n    }\r\n}<\/pre>\n<p>The <em>TodoDTO<\/em> class is a simple DTO class which source code looks as follows:<\/p>\n<pre class=\"brush:java\">import org.hibernate.validator.constraints.Length;\r\nimport org.hibernate.validator.constraints.NotEmpty;\r\n\r\npublic class TodoDTO {\r\n\r\n    private Long id;\r\n\r\n    @Length(max = 500)\r\n    private String description;\r\n\r\n    @NotEmpty\r\n    @Length(max = 100)\r\n    private String title;\r\n\r\n    \/\/Constructor and other methods are omitted.\r\n}<\/pre>\n<p>As we can see, this class declares three validation constraints which are described in the following:<\/p>\n<ol>\n<li>The maximum length of the <em>description<\/em> is 500 characters.<\/li>\n<li>The <em>title<\/em> of a todo entry cannot be empty.<\/li>\n<li>The maximum length of the <em>title<\/em> is 100 characters.<\/li>\n<\/ol>\n<p>If the validation fails, our error handler component ensures that<\/p>\n<ol>\n<li>The HTTP status code 400 is returned to the client.<\/li>\n<li>The validation errors are returned to the client as a JSON document.<\/li>\n<\/ol>\n<p>Because I have already written a <a href=\"http:\/\/www.petrikainulainen.net\/programming\/spring-framework\/spring-from-the-trenches-adding-validation-to-a-rest-api\/\">blog post<\/a> which describes how we can add validation to a REST API, the implementation of the error handler component is not discussed in this blog post.<\/p>\n<p>However, we need to know what kind of a JSON document is returned to the client if the validation fails. This information is given in the following.<\/p>\n<p>If the <em>title<\/em> and the <em>description<\/em> of the <em>TodoDTO<\/em> object are too long, the following JSON document is returned to the client:<\/p>\n<pre class=\"brush:java\">{\r\n    \"fieldErrors\":[\r\n        {\r\n            \"path\":\"description\",\r\n            \"message\":\"The maximum length of the description is 500 characters.\"\r\n        },\r\n        {\r\n            \"path\":\"title\",\r\n            \"message\":\"The maximum length of the title is 100 characters.\"\r\n        }\r\n    ]\r\n}<\/pre>\n<p><strong>Note<\/strong>: Spring MVC does not guarantee the ordering of the field errors. In other words, the field errors are returned in random order. We have to take this into account when we are writing unit tests for this controller method.<\/p>\n<p>On the other hand, if the validation does not fail, our controller method returns the following JSON document to the client:<\/p>\n<pre class=\"brush:java\">{\r\n    \"id\":1,\r\n    \"description\":\"description\",\r\n    \"title\":\"todo\"\r\n}<\/pre>\n<p>We have to write two unit tests for this controller method:<\/p>\n<ol>\n<li>We have to write a test which ensures that our application is working properly when the validation fails.<\/li>\n<li>We have to write a test which ensures that our application is working properly when a new todo entry is added to the database.<\/li>\n<\/ol>\n<p>Let\u2019s find out how we can write these tests.<\/p>\n<h2>Test 1: Validation Fails<\/h2>\n<p>Our first test ensures that our application is working properly when the validation of the added todo entry fails. We can write this test by following these steps:<\/p>\n<ol>\n<li>Create a <em>title<\/em> which has 101 characters.<\/li>\n<li>Create a <em>description<\/em> which has 501 characters.<\/li>\n<li>Create a new <em>TodoDTO<\/em> object by using our test data builder. Set the <em>title<\/em> and the <em>description<\/em> of the object.<\/li>\n<li>Execute a <em>POST<\/em> request to url \u2018\/api\/todo\u2019. Set the content type of the request to \u2018application\/json\u2019. Set the character set of the request to \u2018UTF-8\u2032. Transform the created <em>TodoDTO<\/em> object into JSON bytes and send it in the body of the request.<\/li>\n<li>Verify that the HTTP status code 400 is returned.<\/li>\n<li>Verify that the content type of the response is \u2018application\/json\u2019 and its content type is \u2018UTF-8\u2032.<\/li>\n<li>Fetch the field errors by using the JsonPath expression <em>$.fieldErrors<\/em> and ensure that two field errors are returned.<\/li>\n<li>Fetch all available paths by using the JsonPath expression <em>$.fieldErrors[*].path<\/em> and ensure that field errors about the <em>title<\/em> and <em>description<\/em> fields are found.<\/li>\n<li>Fetch all available error messages by using the JsonPath expression <em>$.fieldErrors[*].message<\/em> and ensure that error messages about the <em>title<\/em> and <em>description<\/em> fields are found.<\/li>\n<li>Verify that the methods of our mock object are not called during our test.<\/li>\n<\/ol>\n<p>The source code of our unit test looks as follows:<\/p>\n<pre class=\"brush:java\">import org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.test.context.ContextConfiguration;\r\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\r\nimport org.springframework.test.context.web.WebAppConfiguration;\r\nimport org.springframework.test.web.servlet.MockMvc;\r\n\r\nimport static org.hamcrest.Matchers.containsInAnyOrder;\r\nimport static org.hamcrest.Matchers.hasSize;\r\nimport static org.mockito.Mockito.*;\r\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;\r\n\r\n@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(classes = {TestContext.class, WebAppContext.class})\r\n@WebAppConfiguration\r\npublic class TodoControllerTest {\r\n\r\n    private MockMvc mockMvc;\r\n\r\n    @Autowired\r\n    private TodoService todoServiceMock;\r\n\r\n    \/\/Add WebApplicationContext field here.\r\n\r\n    \/\/The setUp() method is omitted.\r\n\r\n    @Test\r\n    public void add_TitleAndDescriptionAreTooLong_ShouldReturnValidationErrorsForTitleAndDescription() throws Exception {\r\n        String title = TestUtil.createStringWithLength(101);\r\n        String description = TestUtil.createStringWithLength(501);\r\n\r\n        TodoDTO dto = new TodoDTOBuilder()\r\n                .description(description)\r\n                .title(title)\r\n                .build();\r\n\r\n        mockMvc.perform(post(\"\/api\/todo\")\r\n                .contentType(TestUtil.APPLICATION_JSON_UTF8)\r\n                .content(TestUtil.convertObjectToJsonBytes(dto))\r\n        )\r\n                .andExpect(status().isBadRequest())\r\n                .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))\r\n                .andExpect(jsonPath(\"$.fieldErrors\", hasSize(2)))\r\n                .andExpect(jsonPath(\"$.fieldErrors[*].path\", containsInAnyOrder(\"title\", \"description\")))\r\n                .andExpect(jsonPath(\"$.fieldErrors[*].message\", containsInAnyOrder(\r\n                        \"The maximum length of the description is 500 characters.\",\r\n                        \"The maximum length of the title is 100 characters.\"\r\n                )));\r\n\r\n        verifyZeroInteractions(todoServiceMock);\r\n    }\r\n}<\/pre>\n<p>Our unit test uses two static methods of the <em>TestUtil<\/em> class. These methods are described in the following:<\/p>\n<ul>\n<li>The <em>createStringWithLength(int length)<\/em> method creates a new <em>String<\/em> object with the given length and returns the created object.<\/li>\n<li>The <em>convertObjectToJsonBytes(Object object)<\/em> method converts the object given as a method parameter into a JSON document and returns the content of that document as a <em>byte array<\/em>.<\/li>\n<\/ul>\n<p>The source code of the <em>TestUtil<\/em> class looks as follows:<\/p>\n<pre class=\"brush:java\">import com.fasterxml.jackson.annotation.JsonInclude;\r\nimport com.fasterxml.jackson.databind.ObjectMapper;\r\nimport org.springframework.http.MediaType;\r\n\r\nimport java.io.IOException;\r\nimport java.nio.charset.Charset;\r\n\r\npublic class TestUtil {\r\n\r\n    public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName(\"utf8\"));\r\n\r\n    public static byte[] convertObjectToJsonBytes(Object object) throws IOException {\r\n        ObjectMapper mapper = new ObjectMapper();\r\n        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);\r\n        return mapper.writeValueAsBytes(object);\r\n    }\r\n\r\n    public static String createStringWithLength(int length) {\r\n        StringBuilder builder = new StringBuilder();\r\n\r\n        for (int index = 0; index &lt; length; index++) {\r\n            builder.append(\"a\");\r\n        }\r\n\r\n        return builder.toString();\r\n    }\r\n}<\/pre>\n<h2>Test 2: Todo Entry Is Added to The Database<\/h2>\n<p>The second unit test ensures that our controller is working properly when a new todo entry is added to the database. We can write this test by following these steps:<\/p>\n<ol>\n<li>Create a new <em>TodoDTO<\/em> object by using our test data builder. Set \u201clegal\u201d values to the <em>title<\/em> and <em>description<\/em> fields.<\/li>\n<li>Create a <em>Todo<\/em> object which is returned when the <em>add()<\/em> method of the <em>TodoService<\/em> interface is called.<\/li>\n<li>Configure our mock object to return the created <em>Todo<\/em> object when its <em>add()<\/em> method is called and a <em>TodoDTO<\/em> object is given as a parameter.<\/li>\n<li>Execute a <em>POST<\/em> request to url \u2018\/api\/todo\u2019. Set the content type of the request to \u2018application\/json\u2019. Set the character set of the request to \u2018UTF-8\u2032. Transform the created <em>TodoDTO<\/em> object into JSON bytes and send it in the body of the request.<\/li>\n<li>Verify that the HTTP status code 200 is returned.<\/li>\n<li>Verify that the content type of the response is \u2018application\/json\u2019 and its content type is \u2018UTF-8\u2032.<\/li>\n<li>Get the <em>id<\/em> of the returned todo entry by using the JsonPath expression <em>$.id<\/em> and verify that the <em>id<\/em> is 1.<\/li>\n<li>Get the <em>description<\/em> of the returned todo entry by using the JsonPath expression <em>$.description<\/em> and verify that the <em>description<\/em> is \u201cdescription\u201d.<\/li>\n<li>Get the <em>title<\/em> of the returned todo entry by using the JsonPath expression <em>$.title<\/em> and ensure that the <em>title<\/em> is \u201ctitle\u201d.<\/li>\n<li>Create an <a href=\"http:\/\/docs.mockito.googlecode.com\/hg\/org\/mockito\/ArgumentCaptor.html\" target=\"_blank\"><em>ArgumentCaptor<\/em><\/a> object which can capture <em>TodoDTO<\/em> objects.<\/li>\n<li>Verify that the <em>add()<\/em> method of the <em>TodoService<\/em> interface is called only once and capture the object given as a parameter.<\/li>\n<li>Verify that the other methods of our mock object are not called during our test.<\/li>\n<li>Verify that the <em>id<\/em> of the captured <em>TodoDTO<\/em> object is null.<\/li>\n<li>Verify that the <em>description<\/em> of the captured <em>TodoDTO<\/em> object is \u201cdescription\u201d.<\/li>\n<li>Verify that the <em>title<\/em> of the captured <em>TodoDTO<\/em> object is \u201ctitle\u201d.<\/li>\n<\/ol>\n<p>The source code of our unit test looks as follows:<\/p>\n<pre class=\"brush:java\">import org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.mockito.ArgumentCaptor;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.test.context.ContextConfiguration;\r\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\r\nimport org.springframework.test.context.web.WebAppConfiguration;\r\nimport org.springframework.test.web.servlet.MockMvc;\r\n\r\nimport static junit.framework.Assert.assertNull;\r\nimport static org.hamcrest.Matchers.is;\r\nimport static org.junit.Assert.assertThat;\r\nimport static org.mockito.Mockito.*;\r\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;\r\n\r\n@RunWith(SpringJUnit4ClassRunner.class)\r\n@ContextConfiguration(classes = {TestContext.class, WebAppContext.class})\r\n@WebAppConfiguration\r\npublic class TodoControllerTest {\r\n\r\n    private MockMvc mockMvc;\r\n\r\n    @Autowired\r\n    private TodoService todoServiceMock;\r\n\r\n    \/\/Add WebApplicationContext field here.\r\n\r\n    \/\/The setUp() method is omitted.\r\n\r\n    @Test\r\n    public void add_NewTodoEntry_ShouldAddTodoEntryAndReturnAddedEntry() throws Exception {\r\n        TodoDTO dto = new TodoDTOBuilder()\r\n                .description(\"description\")\r\n                .title(\"title\")\r\n                .build();\r\n\r\n        Todo added = new TodoBuilder()\r\n                .id(1L)\r\n                .description(\"description\")\r\n                .title(\"title\")\r\n                .build();\r\n\r\n        when(todoServiceMock.add(any(TodoDTO.class))).thenReturn(added);\r\n\r\n        mockMvc.perform(post(\"\/api\/todo\")\r\n                .contentType(TestUtil.APPLICATION_JSON_UTF8)\r\n                .content(TestUtil.convertObjectToJsonBytes(dto))\r\n        )\r\n                .andExpect(status().isOk())\r\n                .andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))\r\n                .andExpect(jsonPath(\"$.id\", is(1)))\r\n                .andExpect(jsonPath(\"$.description\", is(\"description\")))\r\n                .andExpect(jsonPath(\"$.title\", is(\"title\")));\r\n\r\n        ArgumentCaptor&lt;TodoDTO&gt; dtoCaptor = ArgumentCaptor.forClass(TodoDTO.class);\r\n        verify(todoServiceMock, times(1)).add(dtoCaptor.capture());\r\n        verifyNoMoreInteractions(todoServiceMock);\r\n\r\n        TodoDTO dtoArgument = dtoCaptor.getValue();\r\n        assertNull(dtoArgument.getId());\r\n        assertThat(dtoArgument.getDescription(), is(\"description\"));\r\n        assertThat(dtoArgument.getTitle(), is(\"title\"));\r\n    }\r\n}<\/pre>\n<h2>Summary<\/h2>\n<p>We have now written unit tests for a REST API by using the Spring MVC Test framework. This tutorial has taught us four things:<\/p>\n<ul>\n<li>We learned to write unit tests for controller methods which read information from the database.<\/li>\n<li>We learned to write unit tests for controller methods which add information to the database.<\/li>\n<li>We learned how we can transform DTO objects into JSON bytes and send the result of the transformation in the body of the request.<\/li>\n<li>We learned how we can write assertions for JSON documents by using JsonPath expressions.<\/li>\n<\/ul>\n<p>As always, the example application of this blog post is available at <a href=\"https:\/\/github.com\/pkainulainen\/spring-mvc-test-examples\/tree\/master\/rest-unittest\" target=\"_blank\">Github<\/a>. I recommend that you check it out because it has a lot of unit tests which were not covered in this blog post.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/www.petrikainulainen.net\/programming\/spring-framework\/unit-testing-of-spring-mvc-controllers-rest-api\/\">Unit Testing of Spring MVC Controllers: REST API<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Petri Kainulainen at the <a href=\"http:\/\/www.petrikainulainen.net\/\">Petri Kainulainen<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release of the Spring MVC Test framework gave us the possibility to write unit tests which are readable, comprehensive and fast. This blog post describes how we can write unit tests &hellip;<\/p>\n","protected":false},"author":429,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[30,150,273],"class_list":["post-16002","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-spring","tag-spring-mvc","tag-testing"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Unit Testing of Spring MVC Controllers: REST API<\/title>\n<meta name=\"description\" content=\"Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Unit Testing of Spring MVC Controllers: REST API\" \/>\n<meta property=\"og:description\" content=\"Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-08-07T10:00:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Petri Kainulainen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/petrikainulaine\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Petri Kainulainen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html\"},\"author\":{\"name\":\"Petri Kainulainen\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/5af4df3fdfeb79e9fa3598d79bff2c9e\"},\"headline\":\"Unit Testing of Spring MVC Controllers: REST API\",\"datePublished\":\"2013-08-07T10:00:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html\"},\"wordCount\":2868,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Spring\",\"Spring MVC\",\"Testing\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html\",\"name\":\"Unit Testing of Spring MVC Controllers: REST API\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2013-08-07T10:00:03+00:00\",\"description\":\"Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/08\\\/unit-testing-of-spring-mvc-controllers-rest-api.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Unit Testing of Spring MVC Controllers: REST API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/5af4df3fdfeb79e9fa3598d79bff2c9e\",\"name\":\"Petri Kainulainen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g\",\"caption\":\"Petri Kainulainen\"},\"description\":\"Petri is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.\",\"sameAs\":[\"http:\\\/\\\/www.petrikainulainen.net\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/in\\\/petrikainulainen\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/petrikainulaine\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/petri-kainulainen\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Unit Testing of Spring MVC Controllers: REST API","description":"Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html","og_locale":"en_US","og_type":"article","og_title":"Unit Testing of Spring MVC Controllers: REST API","og_description":"Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release","og_url":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-08-07T10:00:03+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Petri Kainulainen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/petrikainulaine","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Petri Kainulainen","Est. reading time":"23 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html"},"author":{"name":"Petri Kainulainen","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/5af4df3fdfeb79e9fa3598d79bff2c9e"},"headline":"Unit Testing of Spring MVC Controllers: REST API","datePublished":"2013-08-07T10:00:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html"},"wordCount":2868,"commentCount":5,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Spring","Spring MVC","Testing"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html","url":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html","name":"Unit Testing of Spring MVC Controllers: REST API","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2013-08-07T10:00:03+00:00","description":"Spring MVC provides an easy way to create REST APIs. However, writing comprehensive and fast unit tests for these APIs has been troublesome. The release","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/08\/unit-testing-of-spring-mvc-controllers-rest-api.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Unit Testing of Spring MVC Controllers: REST API"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/5af4df3fdfeb79e9fa3598d79bff2c9e","name":"Petri Kainulainen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9e57425180f323fa65bc519a64c8273d3fcb7c6bd272e56b37dd15613f403659?s=96&d=mm&r=g","caption":"Petri Kainulainen"},"description":"Petri is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.","sameAs":["http:\/\/www.petrikainulainen.net\/","http:\/\/www.linkedin.com\/in\/petrikainulainen","https:\/\/x.com\/https:\/\/twitter.com\/petrikainulaine"],"url":"https:\/\/www.javacodegeeks.com\/author\/petri-kainulainen"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/16002","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/429"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=16002"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/16002\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=16002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=16002"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=16002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}