Enterprise Java

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.

Figure 1. Get API

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.

Figure 2, Test Results

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.

Download
You can download the full source code of this example here: Spring MockMVC Get JSON As Object

Mary Zheng

Mary graduated from the Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She worked as a lead Software Engineer where she led and worked with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button