skip to content

Compare @DataMongoTest with its sibling data slices @DataR2dbcTest, @DataRedisTest, and @DataLdapTest. What does each wire, and what do they share?

level: seniorimportance: should knowfreq 35%

answer

  1. Same skeleton: @OverrideAutoConfiguration(false) + store @AutoConfigure + TypeExcludeFilter
  2. Mongo→MongoTemplate; R2DBC→DatabaseClient/R2dbcEntityTemplate; Redis→RedisTemplate; LDAP→LdapTemplate
  3. R2DBC rolls back per test; Mongo/Redis do not
  4. LDAP → embedded UnboundID; R2DBC → embedded H2 possible
  5. Two stores at once → @SpringBootTest, not a slice

basics

~20 s

Each is a Spring Boot slice that loads only its store's auto-config: @DataMongoTest → Mongo repos + MongoTemplate; @DataR2dbcTest → reactive relational (DatabaseClient/R2dbcEntityTemplate); @DataRedisTest → RedisTemplate + Redis repos; @DataLdapTest → LdapTemplate + LDAP repos. All exclude unrelated beans and disable general auto-config.

solid answer

~40 s

They're one family with identical mechanics but per-store contents. @DataMongoTest wires MongoTemplate/ReactiveMongoTemplate, Mongo repositories, converters, @Document scanning. @DataR2dbcTest wires the reactive relational stack — ConnectionFactory, DatabaseClient, R2dbcEntityTemplate, R2DBC repositories — and is transactional by default (rollback per test) since R2DBC supports transactions, unlike Mongo. @DataRedisTest wires RedisConnectionFactory, RedisTemplate/StringRedisTemplate, and Redis repositories. @DataLdapTest wires LdapTemplate and Spring Data LDAP repositories, and will use an embedded UnboundID LDAP server if that dependency is on the classpath. What they share: each is meta-annotated with @OverrideAutoConfiguration(enabled=false) plus a store-specific @AutoConfigure..., a TypeExcludeFilter to drop @Service/@Controller/@Component, no web/security layer, and reliance on a real backing store (Testcontainers/@ServiceConnection, or embedded where available). Pick the slice matching the datastore under test.

code

java · 26 lines
java
// Reactive relational slice — transactional, rolls back each test
@DataR2dbcTest
class AccountRepositoryTest {
    @Autowired AccountRepository repository;   // extends ReactiveCrudRepository
    @Autowired R2dbcEntityTemplate template;

    @Test
    void findsByOwner() {
        repository.save(new Account("alice", 100)).block();
        StepVerifier.create(repository.findByOwner("alice"))
                    .expectNextCount(1)
                    .verifyComplete();
    }
}

// LDAP slice — embedded UnboundID server if on classpath
@DataLdapTest
class PersonRepositoryTest {
    @Autowired PersonRepository repository;    // Spring Data LDAP repo
    @Autowired LdapTemplate ldapTemplate;

    @Test
    void findsPerson() {
        assertThat(repository.findByCommonName("John Doe")).isNotNull();
    }
}

go deeper

for a junior

Know these are per-store test slices and can name what each store's main template bean is.

for a middle

Explain the shared skeleton and that each wires only its store; know Testcontainers is the usual backing store.

for a senior

Detail the non-uniform transaction/rollback behavior, embedded options (H2 for R2DBC, UnboundID for LDAP), and reactive specifics of R2DBC.

for a principal

Define org-wide slice usage, container/embedded strategy per store, and how multi-store flows escalate to @SpringBootTest; manage context-cache fragmentation.

**One design, many stores.** Spring Boot provides a *data slice* per major datastore. They are structurally identical — each is meta-annotated with `@ExtendWith(SpringExtension.class)`, `@BootstrapWith(...DataXxxTestContextBootstrapper)`, `@OverrideAutoConfiguration(enabled = false)` (turns off Boot's general auto-config so only the slice's explicitly listed auto-config runs), `@TypeExcludeFilters(DataXxxTypeExcludeFilter.class)` (excludes your `@Component`/`@Service`/`@Controller`/`@Configuration`), and one or more `@AutoConfigure...` annotations that pull in exactly that store's beans. The web layer and Spring Security are never part of any of them. What differs is *which store's auto-configuration* each activates. **@DataMongoTest** (`...data.mongo`). Activates MongoDB auto-config: `MongoTemplate`, `ReactiveMongoTemplate`, `MappingMongoConverter`/`MongoCustomConversions`, scanning of `@Document` classes, and creation of `MongoRepository`/`ReactiveMongoRepository` interfaces. **Not transactional/rollback by default.** Needs a real Mongo (Testcontainers `MongoDBContainer` + `@ServiceConnection`, or historically embedded Flapdoodle). **@DataR2dbcTest** (`...data.r2dbc`). Activates the *reactive relational* stack: `ConnectionFactory`, `DatabaseClient`, `R2dbcEntityTemplate`, and R2DBC `ReactiveCrudRepository` interfaces. R2DBC is reactive JDBC-equivalent access to relational DBs. Because relational R2DBC supports transactions, this slice **is transactional and rolls back each test by default** (like `@DataJpaTest`/`@DataJdbcTest`), so tests self-clean. Backing store: an R2DBC-capable DB — embedded H2 via `io.r2dbc:r2dbc-h2`, or Testcontainers Postgres with the r2dbc driver. Note: R2DBC has no schema auto-generation like JPA/Hibernate, so you usually supply a schema (`schema.sql`) or Flyway/Liquibase. **@DataRedisTest** (`...data.redis`). Activates Redis auto-config: `RedisConnectionFactory` (Lettuce), `RedisTemplate`, `StringRedisTemplate`, and Spring Data Redis `@RedisHash` repositories. Redis is a key-value store; there's no rollback semantics, so clean keys between tests. Backing store: Testcontainers Redis (a `GenericContainer` on the Redis image, or a Redis module) — there is no standard embedded Redis in Boot, so a container is the norm. **@DataLdapTest** (`...data.ldap`). Activates LDAP auto-config: `LdapTemplate` and Spring Data LDAP repositories (interfaces annotated with `@Entry`). Uniquely, if the **UnboundID** in-memory LDAP dependency (`com.unboundid:unboundid-ldapsdk`) is on the classpath, Boot starts an **embedded LDAP server** for the test and can load an LDIF, so no external server or container is needed — the closest analog to embedded H2 for JPA. **Shared contract (what to remember).** 1. Slice = only that store's auto-config; everything unrelated (web, security, other stores, your services) is excluded. 2. `@Import`/`@TestConfiguration` to add a specific extra bean; don't over-widen. 3. Real backing store required — Testcontainers + `@ServiceConnection` is the uniform modern answer; embedded options exist for R2DBC-H2 and LDAP-UnboundID. 4. Transaction/rollback behavior is **not** uniform: R2DBC (relational) rolls back per test; Mongo and Redis do **not** — plan cleanup accordingly. 5. Context caching applies to all: identical slice config → one reused context. **Selecting.** Match the slice to the store under test. Testing a reactive Postgres repository → `@DataR2dbcTest`. Caching/rate-limit keys in Redis → `@DataRedisTest`. Directory lookups → `@DataLdapTest`. Document persistence → `@DataMongoTest`. If a test needs two stores at once, no single slice fits — use `@SpringBootTest` (or compose auto-configurations), accepting the heavier context.

  • Why does @DataR2dbcTest roll back each test by default but @DataMongoTest does not?
    R2DBC targets relational databases which support ACID transactions, so the slice (like @DataJpaTest) wraps each test in a transaction rolled back afterward for isolation. MongoDB single-node historically lacked general transaction support, so its slice makes no rollback assumption — you clean data yourself.
  • You need to test a flow that writes to Mongo and caches in Redis in the same test. Which slice do you use?
    None — a single data slice wires only one store. Use @SpringBootTest (full context) or explicitly compose both stores' auto-configurations; the slices are intentionally single-store.
  • How does @DataLdapTest avoid needing an external LDAP server?
    If the UnboundID in-memory LDAP SDK is on the classpath, Boot auto-configures an embedded LDAP server for the test (optionally seeded from an LDIF), similar to how embedded H2 serves JPA slices.

saying these in an interview costs you the question

  • Claiming all data slices roll back per test
  • Thinking one slice can wire two datastores
  • Expecting embedded Redis to appear automatically
  • Assuming R2DBC auto-creates schema like Hibernate ddl-auto

context