$30 off During Our Annual Pro Sale. View Details »

Things I Wish I Knew When I Started Testing Spring Boot Applications

Things I Wish I Knew When I Started Testing Spring Boot Applications

Getting started with Spring Boot and its auto-configuration mechanism can be a hurdle for new developers.

Once you get your first Spring Boot application up- and running, writing tests for it is the last thing you care about. You’re happy that your code does its job.

However, as soon as you try to integrate your changes, you face a pull request rejection because your lead developer reminds you that tests are missing.

Testing is an integral part of software development, and unfortunately, some teams treat this topic neglectfully. That’s bad for the future maintenance and overall health of their project. Fortunately, both Spring Test and Spring Boot offer excellent support for testing your application.

This talk will give you an overview of best practices, pitfalls, and recipes for testing Spring Boot applications. Simply put, with this talk, I’ll share the things that I wish I had known when I started testing Spring Boot applications.

Philip Riecks

October 13, 2022
Tweet

More Decks by Philip Riecks

Other Decks in Technology

Transcript

  1. 1

    View Slide

  2. @rieckpil
    Things I Wish I Knew When I
    Started Testing Spring Boot
    Applications
    🍃

    View Slide

  3. @rieckpil
    My (Not So Effective) Introduction to Testing
    3
    🍃

    View Slide

  4. @rieckpil 4
    🍃

    View Slide

  5. @rieckpil
    Getting Used To Testing At Work
    5
    🍃

    View Slide

  6. @rieckpil
    Getting Used To Testing At Work - Part II
    6
    🍃

    View Slide

  7. @rieckpil
    Goals for This Talk
    Lay the foundation for your
    Spring Boot
    testing success
    Introduction to Spring Boot’s
    excellent test support
    Convince you that testing is not
    an afterthought
    Showcase a mix of best practices
    and early pitfalls
    7
    🍃

    View Slide

  8. @rieckpil
    Agenda for This Talk
    1. Introduction
    2. Things I Wish I Knew When I Started
    a. The Testing Swiss-Army Knife
    b. @SpringBootTest Isn’t Always Your Friend
    c. Slicing aka. You May Not Always Need the Entire Context
    d. JUnit 4 vs. JUnit 5 Pitfall
    3. Where to Go Next?
    4. Conclusion and Q&A
    8
    🍃

    View Slide

  9. @rieckpil
    About Me
    - Freelance IT consultant from Berlin, Germany
    - Enjoys writing blog posts on rainy days in cozy cafes (#TeamWordPress)
    - Blogging & content creation for more than five years. Since two years with a
    focus on testing Java and specifically Spring Boot applications
    - Co-authored Stratospheric - Form Zero to Production With Spring Boot and AWS
    together with Björn Wilmsmann (@bwilmsmann) and Tom Hombergs
    (@TomHombergs)
    - Blog: https://rieckpil.de
    - GitHub: https://github.com/rieckpil/
    - YouTube: https://www.youtube.com/c/rieckpil
    9
    🍃

    View Slide

  10. @rieckpil
    The Testing Swiss-Army Knife
    10
    🍃

    View Slide

  11. @rieckpil
    Your Testing Foundation
    - The Spring Boot Starter Test aka.
    “Testing Swiss-Army Knife“
    - Part of every Spring Boot project
    - Includes everything you need to
    get started with testing Spring
    Boot applications
    11
    🍃

    View Slide

  12. @rieckpil
    Introspecting the
    Swiss-Army Knife
    - Opinionated testing toolbox
    - Upgrade their versions
    consistently when upgrading
    Spring Boot
    - Unless there are no conflicts,
    no need to exclude unused
    libraries as they don’t end up
    in the production JAR
    12
    🍃

    View Slide

  13. @rieckpil
    What’s Inside the Testing Toolbox
    - Core testing framework
    - Successor and rewrite of JUnit 4
    - Extension model, test
    parallelization, dynamic tests,
    parametrized tests, etc.
    13
    🍃

    View Slide

  14. @rieckpil
    What’s Inside the Testing Toolbox
    - Java’s de-facto standard
    mocking library
    - Mock collaborators, stub their
    behavior and verify their
    interaction for testing purposes
    14
    🍃

    View Slide

  15. @rieckpil
    What’s Inside the Testing Toolbox
    AssertJ
    - Assertion library with matchers
    for many types: collections,
    temporals, etc.
    - Fluent and sentence-like
    assertions
    - Write your own custom
    assertions
    15
    🍃

    View Slide

  16. @rieckpil
    What’s Inside the Testing Toolbox
    Hamcrest
    - Fluent assertion library
    - Occasionally used within Spring
    Test, e.g. MockMvc verifications
    - Implementation for many other
    programming languages
    16
    🍃

    View Slide

  17. @rieckpil
    What’s Inside the Testing Toolbox
    JSONAssert
    - Assertion library for JSON data
    structures
    - Compare entire JSON objects
    - Strict and nonstrict assertions
    17
    🍃

    View Slide

  18. @rieckpil
    What’s Inside the Testing Toolbox
    JsonPath
    - Extract data from JSON for
    further assertions using
    JsonPath expressions
    - Use an assertion library of your
    choice for verifying the
    extracted information
    18
    🍃

    View Slide

  19. @rieckpil
    Spring Boot’s Dependency Management
    - Spring Boot manages the
    dependency version of further
    testing libraries
    - Examples: Awaitility, Selenium,
    MockWebServer (from OkHttp)
    19
    🍃
    - Up- or downgrade the version of
    a managed testing library
    version
    - Check the spring-boot-
    dependencies project for a list
    of managed libraries and their
    versions

    View Slide

  20. @rieckpil
    @SpringBootTest Isn’t Always Your Friend
    20
    🍃

    View Slide

  21. @rieckpil
    The Auto-Generated @SpringBootTest Test
    21
    🍃

    View Slide

  22. @rieckpil
    Understanding @SpringBootTest
    22
    🍃
    - Populates the entire
    ApplicationContext based on the
    @SpringBootApplication class
    - Best suited for integration tests
    - Starting your entire application
    requires access to all dependent
    infrastructure components

    View Slide

  23. @rieckpil
    Understanding @SpringBootTest
    23
    🍃
    - Starts the embedded servlet container
    (e.g. Tomcat)
    - Auto-configures the
    WebTestClient/TestRestTemplate
    - Inject the port with
    @LocalServerPort
    - Starts the application with a
    mocked servlet environment
    - No real HTTP communication
    - Use MockMvc to interact with
    the application’s endpoint
    vs.

    View Slide

  24. @rieckpil
    @SpringBootTest Obsession
    24
    🍃
    Testing every single
    class with
    @SpringBootTest
    … results in a lot
    of different
    context setups
    and slows down
    the build

    View Slide

  25. @rieckpil
    @SpringBootTest Obsession: Slower Test Suite
    25
    🍃
    Testing ServiceOne
    with @SpringBootTest
    Testing ServiceTwo
    with @SpringBootTest

    View Slide

  26. @rieckpil
    @SpringBootTest Obsession
    26
    🍃

    View Slide

  27. @rieckpil
    Slicing aka. You May Not Always Need
    the Entire Context
    27
    🍃

    View Slide

  28. @rieckpil 28
    🍃

    View Slide

  29. @rieckpil 29
    🍃
    Creating a much
    smaller context
    with only relevant
    beans

    View Slide

  30. @rieckpil
    Sliced Test Context Example: @WebMvcTest
    30
    🍃
    - Testing our controller endpoints
    in isolation
    - No real HTTP communication
    but a mocked servlet
    environment (MockMvc)
    - Integration with Spring Security
    to verify protection and
    authorization

    View Slide

  31. @rieckpil 31
    🍃

    View Slide

  32. @rieckpil 32
    🍃

    View Slide

  33. @rieckpil
    JUnit 4 vs. JUnit 5 Pitfall
    33
    🍃

    View Slide

  34. @rieckpil
    JUnit 4 vs. JUnit 5 Pitfall
    34
    🍃
    - JUnit 5 is a redesign of JUnit 4, and the next generation of JUnit
    - First release of JUnit 5 in 2017
    - JUnit 5 = JUnit Platform (foundation and TestEngine API) + JUnit Jupiter
    (new programming model) + JUnit Vintage (TestEngine to run JUnit 3
    and 4 tests)
    - We can’t mix both versions within the same test
    - We can run JUnit 4 and 5 tests next to each other thanks to the JUnit
    Vintage engine
    - For automatic migration support, see OpenRewrite

    View Slide

  35. @rieckpil
    Indicators to Differentiate the Version
    35
    🍃
    JUnit 4
    - @Test from org.junit
    - @RunWith
    - @Rule/@ClassRule
    - @Before/@BeforeClass
    - @After/@AfterClass
    - @Ignore
    - @Category
    JUnit 5
    - @Test from
    org.junit.jupiter.api.test
    - @ExtendWith/@RegisterExtension
    - @BeforeEach/@BeforeAll
    - @AfterEach/@AfterAll
    - @Disabled
    - @Tag

    View Slide

  36. @rieckpil
    Where To Go Next?
    36
    🍃
    - Get familiar with the sliced test context annotations that fit your use case
    - Align the test strategy and vocabulary for your project
    - Take some time to learn and understand Spring Boot’s auto-configuration
    - Give Test-Driven Development (TDD) a try
    - Get familiar with your core testing tools: JUnit & Mockito
    - Explore further Java testing libraries like Testcontainers, WireMock, and
    Selenide

    View Slide

  37. @rieckpil
    Testing Spring Boot Applications Masterclass
    - Testing real-world Spring Boot applications
    - 130+ course lessons with 10h+ hands-on video content
    - Tech-Stack: Spring Boot 2.7, PostgreSQL, React 18, Java 17, Keycloak (OAuth
    2 login), communication with a remote HTTP system, async workflows with a
    messaging queue (Amazon SQS)
    - Techniques, pitfalls, and patterns for unit, integration, and end-to-end testing
    - Best of breed testing tools: JUnit 5, Mockito, LocalStack, Testcontainers,
    Awaitility, WireMock, MockWebServer, Selenide, etc.
    - https://rieckpil.de/testing-spring-boot-applications-masterclass/
    37
    🍃

    View Slide

  38. @rieckpil
    Conclusion
    38
    🍃
    - Spring Boot provides a lot of excellent testing tools and emphasizes
    testing
    - Every Spring Boot project comes with a fundamental testing toolbox
    - Ask yourself: “Do I really need to start the entire context for this test?”
    - Use @SpringBootTest for integration tests
    - A sliced context lets you test a specific part in isolation
    - When applying test recipes from other projects (aka. Stack Overflow),
    check the used JUnit version
    - Have fun writing your tests

    View Slide

  39. @rieckpil
    Q&A
    Questions?
    Slides will be uploaded ✅
    The best way to get in contact is via Twitter @rieckpil 👋
    Visit my blog for more testing-related Spring Boot content 🧪
    Enjoy the rest of the conference 🥳
    39
    🍃

    View Slide