Spring MockMVC Get JSON As Object
1. Introduction
Spring MockMVC is the Spring MVC testing framework which performs Spring MVC request handling and response asserting via mocking request and response objects without a running HTTP server. @AutoConfigureMockMvc is used to configure and a MockMVC instance is injected into a test class. In this example, I will demonstrate Spring MockMVC fetch JSON by creating a simple Get Rest API and mocking the response via MockMVC and then converting the response string to an object via both Jackson and GSON libraries.
2. Setup
In this step, I will create a gradle project with spring-boot-starter-web
, Jackson
, GSON
, Lombok
, and Junit
libraries.
build.gradle
plugins { id 'java' id 'org.springframework.boot' version '3.3.0' id 'io.spring.dependency-management' version '1.1.5' } group = 'com.zheng.demo.sbtest' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' implementation 'com.google.code.gson:gson:2.11.0' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() }
3. Get Rest API
3.1 MyRestController
In this step, I will create a MyRestController.java
class which has a Get
method to return a RestReturnData
ResponseEntity
.
MyRestController.java
package com.zheng.demo.sbtest.demo.rest; import java.util.stream.IntStream; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.zheng.demo.sbtest.demo.data.RestReturnData; @RestController public class MyRestController { @GetMapping("/") public ResponseEntity<RestReturnData> getJsonResponse(@RequestParam("input") String input) { RestReturnData retD = new RestReturnData(IntStream.range(0, input.length()).map(n -> (n + 1) * 3).toArray(), input.length(), input); return new ResponseEntity<RestReturnData>(retD, HttpStatus.OK); } }
- Line 18,19: the Get API response is a dummy data generated from the
input
value.
3.2 Response Data
In this step, I will create a RestReturnData.java
class which is used at step 3.1.
RestReturnData.java
package com.zheng.demo.sbtest.demo.data; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class RestReturnData { private int[] someIntArray; private int someNumber; private String someString; }
Note: use the Lombok annotations to reduce the boilerplate code.
3.3 Spring Boot Application
In this step, I will create a DemoApplication.java
annotated with @SpringBootApplication
. Note: if the project is generated from the Spring initializr, then no modification is needed.
DemoApplication.java
package com.zheng.demo.sbtest.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
Start the Spring boot application and navigate to http://localhost:8080/?input=hello and capture the result in the following screenshot.
4. Test Spring MockMVC Fetch JSON
4.1 DemoApplicationTests
In this step, I will run the generated DemoApplicationTests.java
to ensure that the spring boot application is wired correctly. Note: no modification is needed here.
DemoApplicationTests.java
package com.zheng.demo.sbtest.demo; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class DemoApplicationTests { @Test void contextLoads() { } }
4.2 Spring MockMVC Test
In this step, I will create a MyRestControllerTest.java
class which tests the Get
API created at step 3.1.
MyRestControllerTest.java
package com.zheng.demo.sbtest.demo.rest; import static org.hamcrest.Matchers.containsString; 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; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; @SpringBootTest @AutoConfigureMockMvc class MyRestControllerTest { @Autowired private MockMvc mockMvc; @Test void shouldReturnDefaultMessage() throws Exception { this.mockMvc.perform(get("/?input=hello")).andDo(print()).andExpect(status().isOk()) .andExpect(content().string(containsString("hello"))); } }
- Line 16:
@AutoConfigureMockMvc
is configured. - Line 20: a
MockMvc
is autowired by Spring. - Line 24: the mocked instance performs the Get API and response is asserted.
Run this test and capture the output here.
MyRestControllerTest output
2024-06-18T20:56:06.922-05:00 INFO 21400 --- [demo] [ main] c.z.d.s.demo.rest.MyRestControllerTest : Started MyRestControllerTest in 1.587 seconds (process running for 2.604) MockHttpServletRequest: HTTP Method = GET Request URI = / Parameters = {input=[hello]} Headers = [] Body = null Session Attrs = {} Handler: Type = com.zheng.demo.sbtest.demo.rest.MyRestController Method = com.zheng.demo.sbtest.demo.rest.MyRestController#getJsonResponse(String) 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"] Content type = application/json Body = {"someIntArray":[3,6,9,12,15],"someNumber":5,"someString":"hello"} Forwarded URL = null Redirected URL = null Cookies = []
- Line 6: the
Get
request query parameter. - Line 34,35: the
Get
response Json string.
4.3 Spring MockMVC Fetch Json via Gson
In this step, I will create a TestMockMvcViaGson.java
test class which converts the mocked Rest Get
response into POJO via the Gson library.
TestMockMvcViaGson.java
package com.zheng.demo.sbtest.demo.rest; import static org.junit.jupiter.api.Assertions.assertEquals; 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.status; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import com.google.gson.Gson; import com.zheng.demo.sbtest.demo.data.RestReturnData; @SpringBootTest @AutoConfigureMockMvc class TestMockMvcViaGson { @Autowired private MockMvc mockMvc; @Test void use_Gson_to_map_JsonString() { try { String resultString = mockMvc.perform(get("/").param("input", "test_user")).andDo(print()) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); Gson gson = new Gson(); RestReturnData someClass = gson.fromJson(resultString, RestReturnData.class); assertEquals("test_user", someClass.getSomeString()); assertEquals(9, someClass.getSomeNumber()); assertEquals(27, someClass.getSomeIntArray()[8]); } catch (Exception e) { e.printStackTrace(); } } }
- Line 29: create a
gson
instance. - Line 30: convert the JSON string to a Java object via
gson
.
4.4 Spring MockMvc Fetch Json via Jackson
In this step, I will create a TestMockMvcViaJackson.java
test class which converts the mocked Rest Get
response to POJO via Jackson’s objectMapper
.
TestMockMvcViaJackson.java
package com.zheng.demo.sbtest.demo.rest; import static org.junit.jupiter.api.Assertions.assertEquals; 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.status; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import com.fasterxml.jackson.databind.ObjectMapper; import com.zheng.demo.sbtest.demo.data.RestReturnData; @SpringBootTest @AutoConfigureMockMvc class TestMockMvcViaJackson { @Autowired private MockMvc mockMvc; @Test void use_ObjectMapper_to_map_JsonString() { try { String resultString = mockMvc.perform(get("/").param("input", "test_user")).andDo(print()) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); RestReturnData someClass = new ObjectMapper().readValue(resultString, RestReturnData.class); assertEquals("test_user", someClass.getSomeString()); assertEquals(9, someClass.getSomeNumber()); assertEquals(27, someClass.getSomeIntArray()[8]); } catch (Exception e) { e.printStackTrace(); } } }
- Line 30: convert the Json string to a Java object via Jackson’s
objectMapper
.
Run the Junit tests and capture the results as the following screenshot.
5. Conclusion
In this example, I created a Rest Get API via Spring @RestController
and tested it via Spring MockMVC. I also converted the Rest API’s JSON string into POJO via both Jackson and Gson libraries.
6. Download
This was an example of a gradle project.
You can download the full source code of this example here: Spring MockMVC Get JSON As Object