Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
Microservices with Spring Boot and Spring Cloud

You're reading from   Microservices with Spring Boot and Spring Cloud Build resilient and scalable microservices using Spring Cloud, Istio, and Kubernetes

Arrow left icon
Product type Paperback
Published in Aug 2025
Publisher Packt
ISBN-13 9781805801276
Length 810 pages
Edition 4th Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Magnus Larsson Magnus Larsson
Author Profile Icon Magnus Larsson
Magnus Larsson
Arrow right icon
View More author details
Toc

Table of Contents (30) Chapters Close

Preface 1. Getting Started with Microservice Development Using Spring Boot FREE CHAPTER
2. Introduction to Microservices 3. Introduction to Spring Boot 4. Creating a Set of Cooperating Microservices 5. Deploying Our Microservices Using Docker 6. Adding an API Description Using OpenAPI 7. Adding Persistence 8. Developing Reactive Microservices 9. Leveraging Spring Cloud to Manage Microservices
10. Introduction to Spring Cloud 11. Adding Service Discovery Using Netflix Eureka 12. Using Spring Cloud Gateway to Hide Microservices behind an Edge Server 13. Securing Access to APIs 14. Centralized Configuration 15. Improving Resilience Using Resilience4j 16. Understanding Distributed Tracing 17. Developing Lightweight Microservices Using Kubernetes
18. Introduction to Kubernetes 19. Deploying Our Microservices to Kubernetes 20. Implementing Kubernetes Features to Simplify the System Landscape 21. Using a Service Mesh to Improve Observability and Management 22. Centralized Logging with the EFK Stack 23. Monitoring Microservices 24. Installation Instructions for macOS 25. Installation Instructions for Microsoft Windows with WSL 2 and Ubuntu 26. Native Compiled Java Microservices 27. Unlock Your Book’s Exclusive Benefits 28. Other Books You May Enjoy
29. Index

Adding automated microservice tests in isolation

Before we wrap up the implementation, we also need to write some automated tests.

We don’t have much business logic to test at this time, so we don’t need to write any unit tests. Instead, we will focus on testing the APIs that our microservices expose; that is, we will start them up in integration tests with their embedded web server and then use a test client to perform HTTP requests and validate the responses. With Spring WebFlux comes a test client, WebTestClient, that provides a fluent API for making a request and then applying assertions on its result.

The following is an example where we test the composite product API by doing the following tests:

  • Sending in productId for an existing product and asserting that we get back 200 as an HTTP response code and a JSON response that contains the requested productId along with one recommendation and one review
  • Sending in a missing productId and asserting that we get back 404 as an HTTP response code and a JSON response that contains relevant error information

The implementation for these two tests is shown in the following code. The first test looks like this:

@Autowired
private WebTestClient client;
@Test
void getProductById() {
  client.get()
    .uri("/product-composite/" + PRODUCT_ID_OK)
    .accept(APPLICATION_JSON_UTF8)
    .exchange()
    .expectStatus().isOk()
    .expectHeader().contentType(APPLICATION_JSON_UTF8)
    .expectBody()
    .jsonPath("$.productId").isEqualTo(PRODUCT_ID_OK)
    .jsonPath("$.recommendations.length()").isEqualTo(1)
    .jsonPath("$.reviews.length()").isEqualTo(1);
}

The test code works like this:

  • The test uses the fluent WebTestClient API to set up the URL to call “/product-composite/" + PRODUCT_ID_OK and specify the accepted response format, JSON.
  • After executing the request using the exchange() method, the test verifies that the response status is OK (200) and that the response format actually is JSON (as requested).
  • Finally, the test inspects the response body and verifies that it contains the expected information in terms of productId and the number of recommendations and reviews.

The second test looks as follows:

@Test
public void getProductNotFound() {
  client.get()
    .uri("/product-composite/" + PRODUCT_ID_NOT_FOUND)
    .accept(APPLICATION_JSON_UTF8)
    .exchange()
    .expectStatus().isNotFound()
    .expectHeader().contentType(APPLICATION_JSON_UTF8)
    .expectBody()
    .jsonPath("$.path").isEqualTo("/product-composite/" +
     PRODUCT_ID_NOT_FOUND)
    .jsonPath("$.message").isEqualTo("NOT FOUND: " +
     PRODUCT_ID_NOT_FOUND);
}

One important note regarding this test code is that this negative test is very similar to the preceding test in terms of its structure; the main difference is that it verifies that it got an error status code back, Not Found (404), and that the response body contains the expected error message.

To test the composite product API in isolation, we need to mock its dependencies, that is, the requests to the other three microservices that were performed by the integration component, ProductCompositeIntegration. We use Mockito to do this, as follows:

private static final int PRODUCT_ID_OK = 1;
private static final int PRODUCT_ID_NOT_FOUND = 2;
private static final int PRODUCT_ID_INVALID = 3;
@MockitoBean
private ProductCompositeIntegration compositeIntegration;
@BeforeEach
void setUp() {
  when(compositeIntegration.getProduct(PRODUCT_ID_OK)).
    thenReturn(new Product(PRODUCT_ID_OK, "name", 1, "mock-address"));
  when(compositeIntegration.getRecommendations(PRODUCT_ID_OK)).
    thenReturn(singletonList(new Recommendation(PRODUCT_ID_OK, 1,
    "author", 1, "content", "mock address")));
     when(compositeIntegration.getReviews(PRODUCT_ID_OK)).
    thenReturn(singletonList(new Review(PRODUCT_ID_OK, 1, "author",
    "subject", "content", "mock address")));
  when(compositeIntegration.getProduct(PRODUCT_ID_NOT_FOUND)).
    thenThrow(new NotFoundException("NOT FOUND: " +
    PRODUCT_ID_NOT_FOUND));
  when(compositeIntegration.getProduct(PRODUCT_ID_INVALID)).
    thenThrow(new InvalidInputException("INVALID: " +
    PRODUCT_ID_INVALID));
}

The mock implementation works as follows:

  1. First, we declare three constants that are used in the test class: PRODUCT_ID_OK, PRODUCT_ID_NOT_FOUND, and PRODUCT_ID_INVALID.
  2. Next, the @MockitoBean annotation is used to configure Mockito to set up a mock for the ProductCompositeIntegration interface.
  3. If the getProduct(), getRecommendations(), and getReviews() methods are called on the integration component, and productId is set to PRODUCT_ID_OK, the mock will return a normal response.
  4. If the getProduct() method is called with productId set to PRODUCT_ID_NOT_FOUND, the mock will throw NotFoundException.
  5. If the getProduct() method is called with productId set to PRODUCT_ID_INVALID, the mock will throw InvalidInputException.

The full source code for the automated integration tests on the composite product API can be found in the ProductCompositeServiceApplicationTests.java test class.

The automated integration tests on the API exposed by the three core microservices are similar, but simpler since they don’t need to mock anything! The source code for the tests can be found in each microservice’s test folder.

The tests are run automatically by Gradle when performing a build:

./gradlew build

You can, however, specify that you only want to run the tests (and not the rest of the build):

./gradlew test

This was an introduction to how to write automated tests for microservices in isolation. In the next section, we will learn how to write tests that automatically test a microservice landscape. In this chapter, these tests will only be semi-automated. In upcoming chapters, the tests will be fully automated, which is a significant improvement.

lock icon The rest of the chapter is locked
Visually different images
CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Microservices with Spring Boot and Spring Cloud
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Modal Close icon
Modal Close icon