Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Test a Quotes API with Spring Boot 4

In this lab, you will gain hands-on experience adding automated tests to a Spring Boot application, focusing on the Quotes REST API. You will explore multiple testing approaches, including using @SpringBootTest, testing endpoints with TestRestTemplate and MockMvc, and using @MockitoBean to mock service dependencies. By the end of the lab, you will be able to create tests that validate application behavior and API responses.

Lab platform
Lab Info
Level
Beginner
Last updated
Apr 08, 2026
Duration
40m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Introduction

    Welcome to Part 2 of the lab series: Test a Quotes API with Spring Boot 4

    This series of labs introduces the core concepts for creating a RESTful API Service using Spring Boot with the Spring Web dependency.

    In this lab, you will create several different types of tests that verify the Quotes REST API behaves as expected.

    A benefit of using the Spring Initializr template is the added dependency on spring-boot-starter-test.

    This dependency can be seen in the build.gradle file which imports the Spring Boot Test module. This module includes the testing libraries: JUnit, Jupiter, AssertJ, Hamcrest, Mockito, and other useful libraries.

    Thanks to this Spring Boot template, there is little infrastructure that will need to be coded for testing. Simple annotations will help with testing scenarios.

    The tests in this lab are just an introduction to the possible variations of testing available with Spring Boot Test, and will focus on the Core Spring Boot Test library, including JUnit Jupiter and Mockito.

  2. Challenge

    Introduction to @SpringBootTest and @Autowired

    Before testing the REST API features, there are a few basic configurations of a Spring Boot Test class that need to be covered. As with most things with Spring Boot, annotations will be used to configure a class for testing.

    In the BasicTestSetup.java file, you will see an empty class ready to be configured. All of the required imports have already been added to the top of the file.

    To configure this class for testing, add the @SpringBootTest annotation above the class declaration:

    @SpringBootTest
    public class BasicTestSetup {
    

    The @SpringBootTest annotation configures an application context for testing. It loads the full application context and all defined beans, making it suitable for integration-style testing where you want to verify application behavior in a realistic environment.

    The first test will exercise the QuotesService class. As with the application code, this service bean can be injected into the test class by decorating the field containing this bean with the @Autowired annotation:

    @Autowired
    private QuotesService quotesService;
    

    When you annotate a field or a constructor parameter with @Autowired, Spring looks for a bean of the same type and injects it automatically. In this case, the QuotesService is being injected into the test class, so you can test its behavior.

    The class is now configured to write the first test against the QuotesService:

    @Test
    public void quotesServiceShouldReturn3Quotes() {
        var quotes = quotesService.getAllQuotes();
        assertEquals(2, quotes.size());
    }
    

    JUnit Jupiter is a popular testing framework for Java applications. It provides several annotations and assertions that make it easy to write and run tests.

    The @Test annotation marks the method as a test method that should be executed by JUnit.

    The assertEquals() assertion checks that the size of the list of all quotes returned from the QuotesService is 2. For this example code, the QuotesService is hardcoded to return 3 quotes so this assertion will fail.

    Note:

    • assertEquals() is one of several assertions available in the Jupiter library. For more advanced assertion methods, the spring-boot-starter-test has included AssertJ and Hamcrest libraries.
    • It is also important to recognize that this is a contrived example. In real-world scenarios, the number of records returned by a service is usually not deterministic. However, this issue will be addressed later on in this lab.

    To verify that this test is currently failing, execute the following command in the Terminal window:

    ./gradlew test --tests BasicTestSetup
    

    Note: The --tests flag was added to filter the executed tests to just this current class being worked on.

    In the terminal output, you should see BUILD FAILED. If you scroll up in the results, you will see some details as to the failure. Specifically a statement providing the path to the created HTML report. For this lab, you can see this report by opening the link {{localhost:8080}}/build/reports/tests/test/index.html.

    This initial page of the report will give an overview of all tests that have been run. A link to the specific failed test(s) can be seen under the Failed tests tab. Clicking on that link will display the reason this particular test failed. As expected, the test failed because it was looking for 2 quotes, but actually returned 3.

    Fix this failing test by changing the assertion to expect 3 instead of 2 quotes.

    After rerunning the test command, the build should pass and display BUILD SUCCESSFUL.

    This test has started to test the QuotesService class directly, but it does not verify if the /api/quotes endpoint is functioning correctly. The next steps will address this concern.

  3. Challenge

    Introduction to TestRestTemplate

    The prior test class helped you test the QuotesService, but does not test whether the REST API is responding correctly. As seen in Part 1 of this series, you could manually test the REST API by starting the server and executing requests against the embedded server.

    The same types of tests can be automated in a test class using the TestRestTemplate. The TestRestTemplate is a class provided by Spring Boot that makes it easy to test RESTful web services. It provides methods for sending HTTP requests and receiving HTTP responses, similar to a web browser or a REST client.

    In the TestRestTemplateTests.java file, the basics you learned in the previous step have been added. Now that you've seen how to write a basic unit test with Spring Boot it is time to write something a little more interesting that actually tests the REST API.

    The TestRestTemplate client can be injected into this test class using the @Autowired annotation:

    @Autowired
    private TestRestTemplate testRestTemplate;
    

    To enable the TestRestTemplate in the test context, add the following annotation to the test class:

    @AutoConfigureTestRestTemplate
    

    The TestRestTemplate provides methods for sending HTTP requests, which means that this test class will start an embedded web server to handle these requests. So that this embedded web server does not conflict with other applications running on this computer, you can configure the embedded server to use a random port.

    Modify the @SpringBootTest annotation to be:

    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @AutoConfigureTestRestTemplate
    public class TestRestTemplateTests {
    

    Now you can rewrite the previous test to verify that the /api/quotes endpoint is configured to correctly respond with the same number of quotes:

    @Test
    public void quotesEndpointShouldReturn3Quotes () {
        var results = this.testRestTemplate.getForObject("/api/quotes", List.class);
        assertEquals(2, results.size()); 
    }
    

    The getForObject() method sends an HTTP GET request to the /api/quotes endpoint and expects the response to be returned as a List object.

    The assertEquals() method performs the same check against the results, but it is still using the wrong number of results. This helps to verify that the test does actually fail when it should.

    Note: The relative URL /api/quotes can be used because the test class is using an embedded server with a random port.

    To verify that this test is currently failing, execute the following command in the Terminal window:

    ./gradlew test --tests TestRestTemplateTests
    

    You can see the test results report at {{localhost:8080}}/build/reports/tests/test/index.html.

    Note: If you still had the report open from the prior step, but drilled into the failing test, that specific static test class page no longer exists since the above command ran for this particular test class.

    Again, you can fix this failing test by changing the assertion to expect 3 instead of 2 quotes. Then rerun the test command. The build should now pass and display BUILD SUCCESSFUL.

  4. Challenge

    Introduction to MockMVC

    In the previous step, you used the TestRestTemplate class to send HTTP requests and receive HTTP responses. While this is a useful approach for testing the entire stack, depending on the embedded server, it can be slow and cumbersome to set up.

    In this step, you'll use the MockMvc class. This approach allows you to test controller logic without starting an embedded server or sending real HTTP requests. Instead, it performs simulated HTTP requests against your application and verifies the responses.

    Note: This class also provides additional features, like support for testing JSON and XML payloads, among others.

    In the MockMvcTests.java file, the required import statements have been added. You can configure MockMvc using Spring Boot annotations by updating the test class as follows:

    @SpringBootTest
    @AutoConfigureMockMvc 
    public class MockMvcTests {
        
        @Autowired  
        private MockMvc mockMvc;
    

    @AutoConfigureMockMvc tells Spring Boot to automatically configure a MockMvc instance and inject it into the test class using the MockMvc field with the @Autowired annotation.

    Note: If you need more control over the configuration of the MockMvc instance, you could use the MockMvcBuilders utility class.

    Now you can refactor the quotesEndpointShouldReturn3Quotes test from the previous step to use the MockMvc instance:

    @Test
    public void quotesEndpointShouldReturn3Quotes() throws Exception { 
      this.mockMvc.perform(get("/api/quotes"))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.length()").value(3));
    }
    

    Observe that the method signature includes throws Exception for error handling purposes. While the TestRestTemplate handles potential exceptions in a suppressed manner, MockMvc manages them directly in a different approach to test such scenarios.

    The mockMvc.perform() method accepts a RequestBuilder object. This object is being built with the MockMvcRequestBuilders.get() method to send a simulated HTTP GET request to the /api/quotes endpoint.

    Assertions can then be made against the simulated response from this request using various ResultMatchers. These assertions can be chained together using either the andExpect() or andExpectAll() Fluent API methods.

    In this case:

    • The response is first checked that the returned status code is 200 OK.
    • Then the expected JSON response is checked that its length property is equal to the expected 3 quotes.

    By chaining these methods together, you're able to create a single, expressive assertion that checks the length of the JSON array returned by the API. This makes the test more readable and easier to understand than if you were to use multiple lines of code to create the same assertion.

    To run this test, execute the following command:

    ./gradlew test --tests MockMvcTests
    

    You can see the test results report at {{localhost:8080}}/build/reports/tests/test/index.html.

    Compared to the TestRestTemplate, this test should be quicker since it doesn't rely on an embedded server. This is particularly valid when more tests are added.

    This contrived test is still dependent on the QuotesService returning an exact number of quotes. This will be addressed in the next step.

  5. Challenge

    Introduction to MockitoBean

    The previous tests have used the QuotesService instance directly. This worked in this contrived example because the service always returns three quotes. However, this assumption does not hold in a real application, where the service may depend on other components such as a persistence layer. This can lead to fragile tests that rely on implementation details and external dependencies that should not be part of the test.

    To help address this, you can mock the QuotesService so that it returns a controlled result and removes the dependency on other layers.

    In the same MockMvcTests.java file, you can add the following code just above the test method:

    @MockitoBean
    private QuotesService quotesService;
    

    When you add the @MockitoBean annotation, Spring replaces the real QuotesService bean in the application context with a Mockito-based mock.

    By mocking the QuotesService, the test for the /api/quotes endpoint is isolated from its underlying dependencies. This allows you to control the data returned by the service and focus only on the behavior of the controller.

    The Mockito.when() method can now be used to declare what should be returned when the getAllQuotes() method is called.

    At the top of the quotesEndpointShouldReturn3Quotes() test method, add the following lines to mock what is returned by the getAllQuotes() method:

    @Test
    public void quotesEndpointShouldReturn3Quotes() throws Exception { 
        List<String> quotes = Arrays.asList("quote1", "quote2");
        Mockito.when(quotesService.getAllQuotes()).thenReturn(quotes);
    

    In this case, the mock will return a list of 2 quotes. You can now be certain of any assertions made about the behavior of the /api/quotes endpoint.

    Rerun the gradlew test command for this class file:

    ./gradlew test --tests MockMvcTests
    

    Unless you update the expected value in the assertion to 2, you will notice that the build fails again.

    Review the test results report at {{localhost:8080}}/build/reports/tests/test/index.html. You will see that it is now returning 2 quotes instead of 3.

  6. Challenge

    Next Steps

    Congratulations on completing Part 2 of this lab series on Spring!

    You can continue working with this lab to see what improvements you can make.

    Some ideas are to:

    • Create a MockMvc test for the /api/quotes/0 endpoint that mocks the getQuoteByIndex(int index) method.
    • Create a MockMvc test for the POST /api/quotes method. Note that this method returns a 201 Created status.
    • Look up the Hamcrest or AssertJ assertion libraries to see some of the advanced assertions that could be used.

    The best to you as you continue your learning journey here at Pluralsight.

    Hope to see you in Part 3 of this series.

About the author

Jeff Hopper is a polyglot solution developer with over 20 years of experience across several business domains. He has enjoyed many of those years focusing on the .Net stack.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight