You are currently viewing Spring Boot Tutorial with WireMock

Spring Boot Tutorial with WireMock

Spring Boot is a powerful framework for building Java applications with minimal configuration. WireMock is a library for stubbing and mocking web services for testing purposes. In this tutorial, we will integrate WireMock with Spring Boot to demonstrate how you can create and test RESTful services with ease.

Table of Contents

  1. Introduction to Spring Boot
  2. Introduction to WireMock
  3. Setting up a Spring Boot Project
  4. Integrating WireMock
  5. Creating a RESTful Service
  6. Testing with WireMock
  7. Conclusion

1. Introduction to Spring Boot

Spring Boot simplifies the process of building production-ready applications by providing a set of conventions and out-of-the-box functionality. It reduces boilerplate code and allows developers to focus on business logic.

2. Introduction to WireMock

WireMock is a flexible library for stubbing and mocking web services. It allows you to simulate HTTP responses from external services, making it ideal for testing when these services are unavailable or unreliable.

3. Setting up a Spring Boot Project

First, make sure you have Spring Boot installed. You can either use Spring Initializr (https://start.spring.io/) to generate a new project or add the Spring Boot dependencies to your existing project.

For this tutorial, we will create a simple Spring Boot project with Gradle.

Step 1: Create a new Spring Boot project

spring init --name spring-boot-wiremock --dependencies web,devtools spring-boot-wiremock

Step 2: Add WireMock Dependency

Add the WireMock dependency to your build.gradle file:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    developmentOnly 'com.github.tomakehurst:wiremock-jre8:2.30.1'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Step 3: Build and Run

Build and run your Spring Boot application:

./gradlew build
./gradlew bootRun

4. Integrating WireMock

In Spring Boot, you can integrate WireMock by creating a custom configuration.

Step 1: Create WireMock Configuration

Create a new Java class named WireMockConfig:

import com.github.tomakehurst.wiremock.WireMockServer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WireMockConfig {

    @Bean(initMethod = "start", destroyMethod = "stop")
    public WireMockServer wireMockServer() {
        return new WireMockServer(8080);
    }
}

Step 2: Start WireMock with Spring Boot

Modify your main application class to start WireMock along with your Spring Boot application:

import com.github.tomakehurst.wiremock.WireMockServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SpringBootWireMockApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringBootWireMockApplication.class, args);
        WireMockServer wireMockServer = context.getBean(WireMockServer.class);
        wireMockServer.start();
    }

}

5. Creating a RESTful Service

Let’s create a simple RESTful service that retrieves user data.

Step 1: Create User Model

Create a simple User model:

public class User {
    private Long id;
    private String name;
    private int age;
    // Getters and setters
}

Step 2: Create UserController

Create a REST controller to handle user requests:

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // This would normally fetch data from a database
        User user = new User();
        user.setId(id);
        user.setName("John Doe");
        user.setAge(30);
        return user;
    }
}

6. Testing with WireMock

Now let’s write a test to use WireMock to mock an external API call.

Step 1: Write Integration Test

Create an integration test for UserController:

import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
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.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerIntegrationTest {

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(8080);

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGetUser() throws Exception {
        stubFor(get(urlEqualTo("/api/users/1"))
                .willReturn(aResponse()
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"id\": 1, \"name\": \"Mock User\", \"age\": 25}")));

        mockMvc.perform(get("/api/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("Mock User"))
                .andExpect(jsonPath("$.age").value(25));

        verify(getRequestedFor(urlEqualTo("/api/users/1")));
    }
}

In this test:

  • We’re using WireMock’s WireMockRule to create a server that listens on port 8080.
  • We stub a GET request to /api/users/1 with a mocked response.
  • Then, we use MockMvc to perform a GET request to our Spring Boot service.
  • Finally, we verify that WireMock received a request to /api/users/1.

7. Conclusion

WireMock allows you to easily simulate external dependencies, making your tests more robust and independent. This approach ensures that your application behaves as expected, even when external services are not available.

Remember, WireMock is a powerful tool with many more features for more complex testing scenarios. Check out the WireMock documentation for more details and advanced usage.

Leave a Reply