Spring Testing
In-Memory Database
Configure Database
Spring Framework
Testing Setup

Configure specific in memory database for testing purpose in Spring

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Spring tests often become easier to maintain when they run against an in-memory database instead of a shared external instance. The important part is making the test environment explicit so Spring uses the exact in-memory database you chose, rather than silently auto-configuring something you did not intend.

Pick The Database And Scope The Configuration

For most Spring Boot projects, H2 is the usual in-memory choice, but HSQLDB or Derby can work too. The key is to put the test datasource configuration behind a dedicated profile or test-specific property file so it never leaks into production.

A common pattern is application-test.yml plus @ActiveProfiles("test").

yaml
1spring:
2  datasource:
3    url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=PostgreSQL
4    driver-class-name: org.h2.Driver
5    username: sa
6    password:
7  jpa:
8    hibernate:
9      ddl-auto: create-drop
10  sql:
11    init:
12      mode: never

That setup gives your tests a fresh in-memory H2 database while keeping the main application configuration untouched.

Activate The Test Profile

java
1@SpringBootTest
2@ActiveProfiles("test")
3class UserRepositoryIntegrationTest {
4
5    @Autowired
6    private UserRepository userRepository;
7
8    @Test
9    void savesUser() {
10        userRepository.save(new User(null, "Ada"));
11        assertEquals(1, userRepository.count());
12    }
13}

With @ActiveProfiles("test"), Spring loads the test datasource settings instead of the default datasource configuration.

Add The Database Dependency

Your build needs the in-memory driver on the test classpath.

xml
1<dependency>
2    <groupId>com.h2database</groupId>
3    <artifactId>h2</artifactId>
4    <scope>test</scope>
5</dependency>

If you want HSQLDB instead, add that dependency and change the JDBC URL accordingly.

@DataJpaTest And Auto-Replacement

For repository tests, @DataJpaTest is often enough and can automatically configure an embedded database if one is available.

java
1@DataJpaTest
2@ActiveProfiles("test")
3class UserRepositorySliceTest {
4
5    @Autowired
6    private TestEntityManager entityManager;
7
8    @Autowired
9    private UserRepository userRepository;
10
11    @Test
12    void findsPersistedUser() {
13        entityManager.persist(new User(null, "Grace"));
14        assertEquals(1, userRepository.findAll().size());
15    }
16}

This is convenient, but it is still worth declaring the profile and properties explicitly if you want a specific embedded database mode or SQL dialect behavior.

When To Use @AutoConfigureTestDatabase

If your test already defines a datasource and you want Spring Boot to keep it, use:

java
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)

This matters when you switch between an in-memory database and another test datasource, such as Testcontainers. Without understanding replacement behavior, it is easy to think you are testing one database while Spring quietly replaces it with another.

Dialect Compatibility Matters

An in-memory database is fast, but it is not automatically a faithful stand-in for production. H2 can emulate some behavior from other databases, yet vendor-specific SQL, index behavior, and transaction semantics may still differ.

That is why in-memory databases are great for fast repository and service tests, but they are not always enough for final verification of production-specific SQL.

Seed Data And Isolation

Tests become more reliable when each run starts from a known state. You can use schema generation, data.sql, or explicit setup methods. The important thing is to keep tests isolated so one test does not depend on leftover rows from another.

With an in-memory database, that is usually straightforward because the database can be rebuilt per context or per test suite.

Common Pitfalls

A common mistake is putting the in-memory datasource properties in the default application configuration instead of a test-specific profile. Another is assuming @DataJpaTest always uses the exact embedded database you expect without checking the classpath and replacement rules. Developers also often forget that H2 is not the same as PostgreSQL or MySQL, which can hide production-only SQL issues. Finally, reusing one long-lived test context without cleaning data can make tests order-dependent.

Summary

  • Use a dedicated test profile to point Spring at a specific in-memory database.
  • Add the embedded database dependency only to the test scope when appropriate.
  • '@DataJpaTest is convenient, but explicit configuration is still useful.'
  • Understand when Spring replaces your datasource automatically.
  • In-memory databases are excellent for speed, but they do not guarantee full production-dialect fidelity.

Course illustration
Course illustration

All Rights Reserved.