Building a Mock API Framework in Java Using Spring Boot
In modern application ecosystems, integrating with external APIs has become a common necessity. Mocking these third-party APIs enables development and testing without relying on the availability or stability of these services. This guide will walk you through creating a powerful, flexible mock API framework in Java using Spring Boot, from the basics of static and dynamic mocks to building endpoints that can be easily configured and deployed.

Repo : https://github.com/PurnimaSharmaSDET/mockFramework
We’ll also explore:
- How to deploy and configure your mock service on a host server
- Key features like static response support and callback handling
- An overview of popular alternatives like DuckRails
By the end of this guide, you’ll be equipped to build and deploy a mock API framework that can be tailored to the specific needs of any application.
1. Understanding Static vs. Dynamic Mocks
Before diving into the code, let’s cover the difference between static and dynamic mocks:
- Static Mocks: These mocks return a fixed response regardless of input parameters. They’re ideal for testing scenarios where the response is known and doesn’t change. For example, a
GET /user
endpoint might always return a pre-configured user JSON object.
- Dynamic Mocks: These mocks provide responses based on the request parameters or body content. They’re useful for more complex tests where the response should adapt to different inputs. For example, a
GET /user/{id}
endpoint might return different user data based on theid
parameter.
Using Java and Spring Boot, we can configure endpoints that support both static and dynamic responses based on flags, making our framework adaptable to diverse testing needs.
2. Setting Up a Spring Boot Project
To get started, set up a Spring Boot project with the necessary dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
Configuring the Server
For flexibility, assign the server port dynamically using the --server.port
property in the code or environment. This allows the mock service to run on any port, making it easier to integrate with different environments.
# application.yml
server:
port: 8080
Alternatively, override this at runtime:
java -jar mock-service.jar --server.port=8081
3. Creating a Spring Controller with Mock Endpoints
We’ll start with a simple @RestController
that supports both static and dynamic responses for a GET
endpoint at /api/mock/user
.
Step 1: Define the Controller
The MockController
class will contain endpoints with conditional logic to switch between static and dynamic responses based on a flag.
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
@RestController
@RequestMapping("/api/mock")
public class MockController {
@GetMapping("/user")
public ResponseEntity<Object> getUserMock(@RequestParam(required = false) String userId,
@RequestParam(required = false, defaultValue = "false") boolean staticResponse) {
if (staticResponse) {
// Static response
return ResponseEntity.ok(getStaticUserResponse());
} else {
// Dynamic response
return ResponseEntity.ok(getDynamicUserResponse(userId));
}
}
private Object getStaticUserResponse() {
// Fixed user data response
return Map.of("id", "123", "name", "John Doe", "email", "john.doe@example.com");
}
private Object getDynamicUserResponse(String userId) {
// Modify response based on userId
if (userId != null) {
return Map.of("id", userId, "name", "User " + userId, "email", userId + "@example.com");
} else {
return Map.of("error", "No user ID provided");
}
}
}
Example Usage
- Static Mock: The endpoint
/api/mock/user?staticResponse=true
will return a fixed response every time:
{ "id": "123", "name": "John Doe", "email": "john.doe@example.com" }
2. Dynamic Mock: The endpoint /api/mock/user?userId=456
will dynamically generate a response based on userId
:
{ "id": "456", "name": "User 456", "email": "456@example.com" }
4. Deploying Your Mock API on a Host Server
To make your mock API accessible to other services, you need a host server where it can run continuously. Here are some deployment options:
- Cloud Services: Deploy the Spring Boot application on cloud platforms like AWS EC2, Google Cloud, or Azure.
- Containerization: Use Docker to package your application and deploy it on any server.
- Internal Servers: If you’re working in a closed network, deploying on an internal server might be sufficient.
This setup provides flexibility as you can configure third-party services to point to your host server by setting the mock base URL.
5. Enhancing the Framework with POST, PUT, DELETE, and OPTIONS Endpoints
To simulate a full API, add more HTTP methods to the MockController
:
@PostMapping("/user")
public ResponseEntity<Object> createUser(@RequestBody Map<String, Object> userData) {
// Mock create user response
return ResponseEntity.status(201).body(Map.of("status", "User created", "user", userData));
}
@PutMapping("/user/{userId}")
public ResponseEntity<Object> updateUser(@PathVariable String userId, @RequestBody Map<String, Object> userData) {
// Mock update user response
return ResponseEntity.ok(Map.of("status", "User updated", "userId", userId, "updatedData", userData));
}
@DeleteMapping("/user/{userId}")
public ResponseEntity<Object> deleteUser(@PathVariable String userId) {
// Mock delete user response
return ResponseEntity.ok(Map.of("status", "User deleted", "userId", userId));
}
@OptionsMapping("/user")
public ResponseEntity<Object> optionsUser() {
// Mock options response with supported methods
return ResponseEntity.ok(Map.of("methods", List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")));
}
6. Using Ready-Made Mocking Tools: DuckRails
While building a mock API in Spring Boot offers full customization, there are several ready-made tools for simpler mock setups, such as DuckRails. DuckRails allows users to create mock endpoints via a graphical interface without code, making it ideal for lightweight mock requirements.
However, for advanced scenarios and Java-centric teams, building a Spring Boot mock API remains a robust choice due to its flexibility, support for complex logic, and integration potential with larger Java ecosystems.
7. Advanced Customizations: Static Response Flags
Adding a static flag allows you to quickly toggle between static and dynamic responses. This can be especially useful for testing different behaviors without changing the code.
Here’s how you might implement this with a customizable response configuration:
public class MockResponseConfig {
private boolean staticResponse;
private Map<String, Object> staticData;
// Getters and setters
}
@RestController
public class MockController {
@Autowired
private MockResponseConfig responseConfig;
@GetMapping("/api/mock/user")
public ResponseEntity<Object> getUser(@RequestParam(required = false) String userId) {
if (responseConfig.isStaticResponse()) {
return ResponseEntity.ok(responseConfig.getStaticData());
} else {
return ResponseEntity.ok(getDynamicUserResponse(userId));
}
}
}
Conclusion
Creating a Spring Boot-based mock API framework gives you full control over request handling, response customization, and scalability. With endpoints supporting multiple HTTP methods, flexible static/dynamic response toggling, and an easy deployment process, this mock API framework is a solid solution for QA environments.
Mocking third-party dependencies in a controlled way improves testing reliability and reduces reliance on external systems. Whether using Spring Boot or alternatives like DuckRails, creating mock APIs is a valuable skill for any developer working with complex integrations.
Comments
Post a Comment