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 Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  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.

Deepak Mehra user avatar by
Deepak Mehra
·
Jul. 11, 19 · Tutorial
Like (4)
Save
Tweet
Share
68.81K 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, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Full Lifecycle API Management Is Dead
  • Reliability Is Slowing You Down
  • What Are the Benefits of Java Module With Example
  • Monolithic First

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: