Thymeleaf View Testing with Spring Boot and HtmlUnit

Last Updated:  June 23, 2025 | Published: June 23, 2025

Testing web applications effectively requires more than just verifying HTTP responses. While MockMvc excels at testing Spring Boot controllers and REST endpoints, it falls short when we need to test JavaScript interactions, form submissions with client-side validation, or complex user workflows in our Thymeleaf templates. This is where HtmlUnit shines as a powerful testing tool.

HtmlUnit acts as a “GUI-less browser” that can execute JavaScript, manipulate the DOM, and simulate real user interactions. For Spring Boot applications using Thymeleaf templates, this means we can test not just what the server renders, but how users actually interact with our pages.

In this article, we’ll explore how to leverage HtmlUnit with Spring Boot 3.5 and Java 21 to create comprehensive tests for Thymeleaf views.

Setting up HtmlUnit with Spring Boot

Spring Boot 3.5 includes HtmlUnit support through the standard test starter, making integration seamless. Let’s start with a practical example: a customer management system with forms and tables.

First, ensure your pom.xml includes the necessary dependencies:

Note that we can omit the version for the HtmlUnit dependency as it is managed by the Spring Boot parent POM.

Let’s create a Customer entity and controller:

Note: For demonstration purposes, we’re using the entity directly with bean validation annotations. In production-grade applications, you should separate your JPA entities from your request/form objects to maintain clean separation of concerns and avoid tight coupling between your domain model and presentation layer.

Now let’s create the controller:

Now, let’s create the Thymeleaf templates. First, the form template (customers/form.html):

And the list template (customers/list.html):

Testing Thymeleaf views with HtmlUnit

Now we can write comprehensive tests using HtmlUnit.

The key advantage is that HtmlUnit executes JavaScript, allowing us to test client-side validation and dynamic behavior.

Let’s explore three essential testing scenarios with step-by-step explanations.

Understanding the basic test setup

First, let’s understand how to set up a test class for HtmlUnit.

Note that when using HtmlUnit with MockMvc, you’ll need to configure the WebClient properly:

What each annotation does:

  • @WebMvcTest(CustomerController.class) – Creates a test slice that only loads our CustomerController and web layer components, and automatically configures MockMvc and HtmlUnit WebClient
  • @Autowired WebClient webClient – This is our “browser” that can navigate pages and click buttons. Important: This is HtmlUnit’s WebClient, not the Spring WebFlux WebClient – they are different classes with the same name
  • @MockitoBean CustomerService customerService – Creates a mock version of our service so we can control its behavior in tests

Example 1: Testing form submission with valid data

Let’s start with a complete form submission test:

Key concepts explained:

  • HtmlPage – Represents the entire web page, like what you see in your browser
  • HtmlForm – Represents a <form> element
  • setValueAttribute("John Doe") – Types “John Doe” into the name field
  • ArgumentCaptor – Captures the arguments passed to our mock service so we can verify them

Example 2: Testing JavaScript validation

Here’s where HtmlUnit really shines – it can execute JavaScript and test client-side behavior:

What’s happening:

  • JavaScript executes when we click submit, preventing form submission for invalid data
  • isDisplayed() – Checks if an element is visible on the page
  • never().save(any()) – Verifies our service was never called when validation fails
  • HtmlUnit runs the actual JavaScript code from our template

Important note about HTML5 validation: HtmlUnit respects HTML5 form validation attributes. If you use <input type="email">, HtmlUnit will prevent form submission with invalid email formats, just like a real browser. In our test, we had to provide a valid email format before testing JavaScript validation for the name field.

Example 3: Testing table content and navigation

Let’s test our customer list page with table data and sorting links:

Important concepts:

  • PageImpl – Creates a fake page of results for our mock
  • getHtmlElementById("customers-table") – Finds element with id="customers-table"
  • getCell(0) – Gets the first cell in a table row
  • getAnchorByHref() – Finds a link (<a> tag) with specific href attribute
  • times(2) – Service called twice: once for initial page load, once after clicking

Comparing HtmlUnit and MockMvc approaches

Understanding when to use each tool is crucial for effective testing.

Let’s compare both approaches with practical examples.

MockMvc: Fast controller testing

MockMvc excels at testing controller logic and HTTP interactions:

MockMvc provides faster execution and is ideal for:

  • Unit testing individual controllers
  • Verifying request/response mappings
  • Testing security configurations
  • Quick feedback during development

HtmlUnit: JavaScript and user interaction testing

HtmlUnit shines when testing JavaScript functionality and complex user workflows:

HtmlUnit offers comprehensive testing capabilities for:

  • JavaScript validation and interactions
  • Multi-page user workflows
  • Form submissions with client-side logic
  • Testing the actual rendered HTML structure

Summary of using HtmlUnit with Thymeleaf and Spring Boot

Testing Thymeleaf views effectively requires understanding the strengths of both MockMvc and HtmlUnit. While MockMvc provides fast, lightweight testing for controllers and basic view rendering, HtmlUnit enables comprehensive testing of JavaScript interactions, form validations, and complete user workflows that MockMvc simply cannot handle.

For Spring Boot applications, the integration is seamless through the spring-boot-starter-test dependency.

HtmlUnit’s ability to execute JavaScript makes it invaluable for testing modern web applications where client-side behavior is crucial to the user experience. By combining both tools strategically, we can create a robust testing suite that ensures our Thymeleaf views work correctly from both server-side rendering and client-side interaction perspectives.

The key is to use MockMvc for rapid feedback during development and basic controller testing, while leveraging HtmlUnit for integration tests that verify the complete user experience. This balanced approach provides confidence that our Spring Boot applications deliver the functionality users expect while maintaining reasonable test execution times.

Joyful testing,

Philip

>