DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4
  • Generate Unit Tests With AI Using Ollama and Spring Boot
  • How Spring Boot Starters Integrate With Your Project

Trending

  • The Death of "Text-Only" ChatOps: Why Google's A2UI Matters for DevOps and SRE
  • How AI Coding Assistants Are Changing Developer Flow
  • You Learned AI. So Why Are You Still Not Getting Hired?
  • Understanding MCP Architecture: LLM + API vs Model Context Protocol
  1. DZone
  2. Coding
  3. Frameworks
  4. Spring Boot WebClient and Unit Testing

Spring Boot WebClient and Unit Testing

Learn more about the Spring Boot WebClient and writing your own unit test cases.

By 
Deepak Mehra user avatar
Deepak Mehra
·
Jul. 11, 19 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
75.2K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, we will talk about the Spring Boot WebClient. If you are using Spring WebFlux, you can choose to use WebClient to call external rest services. It was introduced in Spring 5 as part of the web reactive framework that helps build reactive and non-blocking web applications.

WebClient is simply an interface that offers methods to make calls to rest services. This includes methods like GET, POST, PUT, PATCH, DELETE, and OPTIONS. You can leverage any of these methods to make calls to the external service asynchronously.

The main advantage of using the WebClient is that it is reactive, as it uses Webflux and is also non-blocking by nature and the response will always be returned in either Mono or Flux. So, make sure you are using Spring WebFlux already if you plan to use WebClient to make API calls.

How to Use Spring WebClient?

Note that I would be using a Maven build tool to show the demo. If you are using any other build tool, please find the dependency on the Internet, as they should be easily available.

Step 1. Add Spring WebFlux dependency to you POM.XML

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>


Step 2. Create an interface with a method that will return the response from the REST call.

public interface ContentService {
    public Mono<Post> getPost(int id);
}


Step 3. Create a ServiceImpl class that will have the implementation of the Service interface created in Step 2.

@Service
public class ContentServiceImpl implements ContentService {

    private static final Logger LOGGER = Logger.getLogger(ContentServiceImpl.class.getName());

    private final WebClient webClient;

    public ContentServiceImpl(@Value("${content-service}") String baseURL) {
        this.webClient = WebClient.builder().baseUrl(baseURL)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
                .filter(logRequest())
                .build();
    }

    @Override
    public Mono<Post> getPost(int id) {
        return webClient.get().uri("posts/{id}", id).retrieve().bodyToMono(Post.class);
    }

}


In step 3, we have created an instance of WebClient and initialized it by using the WebClient builder. It will then create a WebClient object and also allow you to customize your call with several methods that it offers. Please refer to all the methods while you use it.

You can choose HTTP methods, depending upon the nature of the HTTP call, and make a request to it. In the scenario above, we are leveraging the GET method and returning a response from the API call.

The method getPost is the method that will be making the request with the help of the WebClient instance and retrieve the response from an external API call. If you have to make a POST call, you can leverage the POST method. And in that case, you will have to pass a body to the method body; there are a lot of methods to play around with. Once you start to use it, you will have various methods to put in use for sure.

How to Handle Errors

To handle errors in WebClient, you can use extend retrieve method. The retrieve method in WebClient throws an  WebClientResponseException when there will be a 4xx and 5xx series exception received. You can further customize it using the  onStatus() method, like below.
.retrieve()
            .onStatus(HttpStatus::is4xxClientError, response ->
                Mono.error(new MyCustomException())
            )
            .onStatus(HttpStatus::is5xxServerError, response ->
                Mono.error(new MyCustomException())
            )
            .bodyToFlux(Post.class);


Unlike the .retrieve() method, the .exchange() method will not be throwing exceptions in case 4xx and 6xx series exception from the other end. So, it is always recommended to use the .retrieve()  method so that you can find the real cause of the exception and pass it further to the client after wrapping it in a Custom Exception. And if you can want to silence the exception and move further, you can use .exchange() method (which, however, I am not recommending).

Writing Unit Test Cases for WebClient

Writing unit test cases for WebClient is a little tricky, as it includes the use of a library called the MockWebServer.

Below is the Maven dependency for that library. Once you add the library dependency, you can start to write the test cases for WebClient.

How to Write Test Cases

Step 1. First, create an object of MockWebServer, like below:

private final MockWebServer mockWebServer = new MockWebServer();


Step 2. Once the object is created, you can stub the mock response, like below:

mockWebServer.enqueue(
                new MockResponse()
                        .setResponseCode(200)
                        .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .setBody("{\"userId\": 1,\"id\": 1, \"title\": \"sunt aut facere repellat p


Now, you can simply assert the actual response with the expected response.

That's it, we are good to go! In this article, we learned both how to make HTTP calls using WebClient and how to write unit test cases designed for testing the functionality.

Please refer to GitHub for full code access, and let us know your thoughts down in the comments below.

Spring Framework unit test Spring Boot

Published at DZone with permission of Deepak Mehra. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4
  • Generate Unit Tests With AI Using Ollama and Spring Boot
  • How Spring Boot Starters Integrate With Your Project

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook