skip to content

What is @DataMongoTest and what does it wire up?

level: juniorimportance: must knowfreq 55%

answer

  1. Slice = only Mongo auto-config, not full context
  2. MongoTemplate + Mongo repositories + @Document scan
  3. No @Service/@Controller scanned — @Import to add
  4. Needs real Mongo: Testcontainers + @ServiceConnection
  5. Not transactional/rollback like @DataJpaTest

basics

~20 s

@DataMongoTest is a Spring Boot test slice that loads only the MongoDB-related parts of the context — your Spring Data Mongo repositories and MongoTemplate — instead of the whole application, so repository tests start fast.

solid answer

~40 s

@DataMongoTest is a Spring Boot sliced-test annotation for MongoDB persistence. Instead of booting the full ApplicationContext like @SpringBootTest, it configures only Mongo-relevant auto-configuration: MongoTemplate, ReactiveMongoTemplate, your Spring Data MongoDB repositories, converters, and @Document scanning. It disables everything unrelated — web layer, JPA, security, your @Service/@Component beans are not scanned. By default it is transactional-agnostic (Mongo lacked broad transaction support historically) and it expects a MongoDB instance; historically it used an embedded Mongo (Flapdoodle) if present, but modern practice is Testcontainers via @ServiceConnection. Use it to test repository queries, custom repository methods, and MongoTemplate operations in isolation and fast. If you need a @Service bean too, either import it with @Import or use @SpringBootTest.

code

java · 19 lines
java
@DataMongoTest
@Testcontainers
class ProductRepositoryTest {

    @Container
    @ServiceConnection // Boot wires the container's URI into Mongo auto-config
    static MongoDBContainer mongo = new MongoDBContainer("mongo:7");

    @Autowired ProductRepository repository;
    @Autowired MongoTemplate mongoTemplate;

    @Test
    void savesAndFindsByName() {
        repository.save(new Product("widget", 9.99));

        assertThat(repository.findByName("widget")).isPresent();
        assertThat(mongoTemplate.getCollectionNames()).contains("product");
    }
}

go deeper

for a junior

Know it loads only Mongo repositories + MongoTemplate, not the whole app, and is faster than @SpringBootTest.

for a middle

Explain what's excluded (@Service/web/security), how to @Import extra beans, and that it needs a real Mongo via Testcontainers.

for a senior

Discuss the meta-annotation machinery (@OverrideAutoConfiguration, TypeExcludeFilter), @ServiceConnection wiring, and the no-rollback difference vs @DataJpaTest.

for a principal

Weigh slice vs full-context testing strategy across the pyramid, container reuse/cleanup costs, and when a shared slice family (@DataR2dbcTest etc.) belongs in the test architecture.

## Test slices in Spring Boot A *slice test* loads a narrow, focused subset of the Spring application context rather than the whole thing. The full-context annotation is `@SpringBootTest`, which starts everything your app has (web server, all beans, all auto-configuration). Slices trade completeness for speed and isolation: they include only the auto-configuration relevant to one layer. Examples are: - `@WebMvcTest` (web/MVC only), - `@DataJpaTest` (JPA repositories), - and the one here, `@DataMongoTest` (MongoDB persistence). ## What the slice includes and excludes **What @DataMongoTest includes.** `@DataMongoTest` (in package `org.springframework.boot.test.autoconfigure.data.mongo`) applies the MongoDB auto-configurations and nothing unrelated. Concretely you get: - `MongoTemplate` and `ReactiveMongoTemplate` (the low-level operations classes), - the mapping/converter infrastructure (`MappingMongoConverter`, custom `MongoCustomConversions`), - scanning of `@Document` entity classes, - and creation of your Spring Data MongoDB repository interfaces (things extending `MongoRepository` or `ReactiveMongoRepository`). It is meta-annotated with: - `@BootstrapWith(DataMongoTestContextBootstrapper.class)`, - `@ExtendWith(SpringExtension.class)`, - `@OverrideAutoConfiguration(enabled=false)` (turns off *general* auto-config so only the explicitly listed slice auto-config runs), - `@TypeExcludeFilters(DataMongoTypeExcludeFilter.class)`, - and `@AutoConfigureDataMongo` / `@AutoConfigureCache`. **What it excludes.** Regular `@Component`, `@Service`, `@Controller`, `@Configuration` you wrote are **not** scanned. The web layer, Spring Security filter chain, JPA, and other datastores are not configured. So a test that needs a business service must bring it in explicitly (see below). ## Getting a MongoDB instance A Mongo slice still needs a real Mongo to talk to (unlike an in-memory H2 for JPA). Two common approaches: - (1) **Testcontainers** — declare a `@Container MongoDBContainer` and, on Boot 3.1+, annotate it `@ServiceConnection` so Boot wires the container's host/port into the Mongo auto-config automatically (no manual `spring.data.mongodb.uri` property). - (2) Historically **embedded Mongo** via the Flapdoodle `de.flapdoodle.embed.mongo` dependency, which `@DataMongoTest` would auto-detect; embedded Mongo auto-configuration was deprecated/removed in newer Boot, so Testcontainers is the recommended path today. ## Bringing in extra beans - If your test needs a collaborator that the slice doesn't scan (e.g., a `@Service` that wraps a repository), add `@Import(MyService.class)`. - To register additional test configuration, use a nested `@TestConfiguration` class. - To *widen* the auto-config (e.g., add another slice) you can add more `@AutoConfigure...` annotations, but at that point `@SpringBootTest` may be simpler. ## Transactions Unlike `@DataJpaTest`, `@DataMongoTest` does **not** wrap each test in a rollback transaction by default — MongoDB single-node historically had no transactions, and rollback-per-test isn't assumed. This means data you write persists across tests unless you clean up (e.g., drop the collection in `@BeforeEach`/`@AfterEach` or `mongoTemplate.getDb().drop()`), and Testcontainers gives you a fresh container per class if configured that way. ## Sibling slices (same family) Spring Boot ships one slice per major store, each wiring only that store's auto-config: - `@DataR2dbcTest` (reactive relational — `DatabaseClient`, `R2dbcEntityTemplate`, R2DBC repositories), - `@DataRedisTest` (`RedisTemplate`, `StringRedisTemplate`, Redis repositories), - `@DataLdapTest` (`LdapTemplate`, LDAP repositories, with embedded UnboundID LDAP if on classpath), - plus `@DataJpaTest`, `@DataJdbcTest`, `@DataCassandraTest`, `@DataCouchbaseTest`, `@DataNeo4jTest`, `@DataElasticsearchTest`. They all share the same design: `@OverrideAutoConfiguration(enabled=false)` + a store-specific `@AutoConfigure...`, exclude unrelated components, and are meant for fast, focused persistence tests. ## When to use - Reach for `@DataMongoTest` when you want to test repository query derivation, custom `@Query` methods, aggregation via `MongoTemplate`, index creation, or converter mapping — without the cost and coupling of the full app. - Reach for `@SpringBootTest` when the behavior spans multiple layers (controller → service → repo) or needs many beans.

  • Your @DataMongoTest needs a @Service that wraps the repository. How do you get that bean into the slice?
    The slice does not scan @Service beans, so add @Import(MyService.class) on the test class (or register it via a nested @TestConfiguration). If many beans are needed, consider @SpringBootTest instead.
  • How does the test get a MongoDB to talk to?
    Provide one — modern approach is a Testcontainers MongoDBContainer annotated @ServiceConnection so Boot auto-wires its URI. Historically an embedded Flapdoodle Mongo on the classpath was auto-detected, but that path is deprecated in newer Boot.

saying these in an interview costs you the question

  • Thinking @DataMongoTest loads the whole app context
  • Assuming it scans @Service/@Component beans automatically
  • Believing it rolls back each test in a transaction like @DataJpaTest
  • Assuming an in-memory Mongo always exists without any dependency/container

context