Tag Archives: Testing

Testing — unit testing, integration testing, and test automation in Java

A Developer’s Guide to Testing Spring REST Clients with @RestClientTest

In modern microservices architecture, it’s rare for a service to live in complete isolation. Most applications need to communicate with other services over the network, typically via REST APIs. When you build a component that consumes an external REST API, a critical question arises: how do you test it reliably without actually making network calls to a live, and potentially unstable, external service?

This is where Spring Boot’s test slices come to the rescue. For testing your REST clients, the framework provides a powerful and elegant solution: the @RestClientTest annotation. Let’s dive deep into how you can use it to write clean, fast, and reliable tests for your HTTP client components.

What Exactly is @RestClientTest?

@RestClientTest is a “test slice” annotation specifically designed to test REST client components. Instead of loading your entire Spring application context (like @SpringBootTest does), it focuses only on the beans relevant to REST client operations. This makes your tests significantly faster and less prone to side effects from unrelated configurations.

When you use @RestClientTest, Spring Boot will auto-configure the following for you:

  • The Client Under Test: The specific REST client bean you want to test.
  • MockRestServiceServer: A bean that lets you mock the server-side responses. You can instruct it: “When my client calls /api/employees/1, respond with this specific JSON.”
  • RestTemplateBuilder: Used to help construct RestTemplate instances.
  • Jackson/Gson Support: It automatically includes support for serializing and deserializing JSON, so you can test your client-side data mapping.

In short, it provides the perfect, minimal environment to verify that your client builds the correct HTTP request and correctly parses the HTTP response — all without a single packet leaving your machine.

Continue reading A Developer’s Guide to Testing Spring REST Clients with @RestClientTest

Testing Hibernate 7: Mocking JNDI DataSources Without the Container

Testing enterprise applications can be a nightmare when your code relies on a JNDI (Java Naming and Directory Interface) DataSource. You shouldn’t need a full-blown JBoss or WildFly server just to run a single unit test.

If you are upgrading to Hibernate 7, you might notice that the way we handle container-managed resources has evolved. In this guide, we will explore how to mock an in-memory JNDI DataSource so your tests remain fast, isolated, and reliable without the overhead of an application server.

The Problem: The “NamingException” Wall

You’ve written a perfect Data Access Object (DAO) or Service layer. It works beautifully in production because the application server (like GlassFish, Payara, or WildFly) provides the JNDI lookup.

However, the moment you run a JUnit 5 test in your IDE, you hit the dreaded javax.naming.NoInitialContextException or NamingException. The environment outside the container doesn’t have a JNDI provider. The InitialContext is empty, and Hibernate fails to boot because it cannot find the resource it needs. You’re stuck between two bad choices: either skip database testing entirely or install a heavy container locally.

The Agitation: Why “Real” JNDI is a Testing Antipattern

Relying on a real JNDI provider for local development or CI/CD pipelines creates several bottlenecks:

  1. Feedback Loop Latency: Starting an application server adds minutes to your build time. For a developer, a 10-second test suite is a productivity booster; a 10-minute suite is a distraction.
  2. Environmental Drift: If the server configuration changes in the dev environment but not in the test environment, your tests break—not because of your code, but because of the infrastructure.
  3. The Jakarta EE 10/11 Shift: Hibernate 7 introduces tighter integration with Jakarta EE 10 and 11. Older mocking hacks—like manually overriding the InitialContextFactory with custom inner classes—often fail due to stricter class-loading mechanisms and the updated jakarta.resource and jakarta.transaction APIs.

The Solution: Simple-JNDI and Hibernate 7

The most robust way to solve this is by using Simple-JNDI, a library that provides a file-based or memory-based JNDI implementation specifically designed for testing environments. By combining this with the H2 database, we can simulate a production-grade DataSource in milliseconds.

Continue reading Testing Hibernate 7: Mocking JNDI DataSources Without the Container

Master Hibernate 7: Configuring In-Memory Databases for Bulletproof Unit Testing

Testing database logic is often the “Achilles’ heel” of Java development. You want your tests to be fast, but you also want them to be accurate. If you’ve ever felt the frustration of a slow CI/CD pipeline or flaky tests caused by a shared development database, you aren’t alone.

In this guide, we will dive deep into how to configure an in-memory database to unit test Hibernate 7. By moving away from heavy, external instances and toward lightweight, transient databases like H2 or HSQLDB, you can achieve lightning-fast feedback loops while ensuring your data mapping logic remains robust.

The Problem: The Database Bottleneck

Traditional unit tests that hit a “real” database (like PostgreSQL or MySQL) suffer from several systemic issues:

  1. Slowness: Network latency and disk I/O make tests crawl.
  2. Pollution: Shared state between tests leads to “leaky” data and unpredictable failures.
  3. Environment Hell: Differences between a developer’s local DB and the build server configuration.
  4. Schema Desync: The manual burden of keeping a test schema in sync with production.

The Agitation: The Cost of “Shallow” Testing

When tests take too long, developers stop running them. This leads to a dangerous reliance on mocking EntityManager or Session.

Mocking is a “shallow” test; it verifies that a method was called, but it doesn’t verify that the SQL generated by Hibernate is actually valid for your schema. Imagine a scenario where a simple @Column rename or a complex @OneToMany mapping breaks production because your mocks couldn’t simulate a constraint violation. You need a solution that provides the confidence of a real database with the speed of a mock.

The Solution: Hibernate 7 + In-Memory H2

The solution is to use an In-Memory Database. For Hibernate 7, the most popular choice is H2. It is lightweight, supports standard SQL, and resides entirely in your system’s RAM.

Continue reading Master Hibernate 7: Configuring In-Memory Databases for Bulletproof Unit Testing