Spring Boot
MongoRepository
Unit Testing
Software Development
Java

How to unit test a Spring Boot MongoRepository?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Testing a Spring Boot MongoRepository is most effective when repository behavior is isolated from service logic. You want fast tests that validate mapping, query methods, and persistence assumptions without booting the entire application. In practice, teams combine focused @DataMongoTest cases with a smaller set of container-backed tests for realistic Mongo behavior.

Build a Focused Repository Test Slice

@DataMongoTest loads Mongo components and avoids full web startup, which keeps tests quick and deterministic.

Repository example:

java
1import org.springframework.data.mongodb.repository.MongoRepository;
2
3import java.util.Optional;
4
5public interface UserRepository extends MongoRepository<User, String> {
6    Optional<User> findByEmail(String email);
7}

Test with @DataMongoTest:

java
1import org.junit.jupiter.api.Test;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
4
5import static org.assertj.core.api.Assertions.assertThat;
6
7@DataMongoTest
8class UserRepositoryTest {
9
10    @Autowired
11    private UserRepository repository;
12
13    @Test
14    void findsUserByEmail() {
15        repository.save(new User("u1", "[email protected]", "Alice"));
16
17        var result = repository.findByEmail("[email protected]");
18        assertThat(result).isPresent();
19        assertThat(result.orElseThrow().getName()).isEqualTo("Alice");
20    }
21}

This verifies query derivation and basic persistence semantics with minimal overhead.

Keep Test Data Explicit and Small

Avoid shared global fixtures that hide test intent. Build test objects per method and assert one behavior per test.

java
1@Test
2void returnsEmptyWhenEmailNotFound() {
3    repository.save(new User("u2", "[email protected]", "Bob"));
4
5    var result = repository.findByEmail("[email protected]");
6    assertThat(result).isEmpty();
7}

Small setup blocks reduce coupling and make failures faster to diagnose.

Use Testcontainers for High-Confidence Database Behavior

Some repository behavior can differ across embedded substitutes and real MongoDB versions. When this matters, add a container-backed test layer.

java
1import org.junit.jupiter.api.Test;
2import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
3import org.springframework.test.context.DynamicPropertyRegistry;
4import org.springframework.test.context.DynamicPropertySource;
5import org.testcontainers.containers.MongoDBContainer;
6import org.testcontainers.junit.jupiter.Container;
7import org.testcontainers.junit.jupiter.Testcontainers;
8
9@DataMongoTest
10@Testcontainers
11class UserRepositoryContainerTest {
12
13    @Container
14    static MongoDBContainer mongo = new MongoDBContainer("mongo:7.0");
15
16    @DynamicPropertySource
17    static void overrideProps(DynamicPropertyRegistry registry) {
18        registry.add("spring.data.mongodb.uri", mongo::getReplicaSetUrl);
19    }
20
21    @Test
22    void savesAndLoadsDocument(org.springframework.beans.factory.annotation.Autowired UserRepository repository) {
23        repository.save(new User("u3", "[email protected]", "Cara"));
24        assert repository.findByEmail("[email protected]").isPresent();
25    }
26}

Container tests run slower, so keep them focused on cases where real Mongo behavior matters.

Verify Repository Contracts, Not Service Logic

Repository tests should answer persistence questions:

  • Does query derivation return expected documents.
  • Are field mappings correct.
  • Are null and empty cases handled.

Business rules, orchestration, and validation logic belong in service tests. Mixing layers creates brittle tests and unclear failures.

Control Test Isolation

Mongo tests can become order dependent if state leaks between methods. Cleanup explicitly in setup hooks or use isolated collections per test class.

java
1import org.junit.jupiter.api.BeforeEach;
2
3@BeforeEach
4void clean() {
5    repository.deleteAll();
6}

Isolation is especially important for parallel test runs in CI.

Assert Indexed Query Behavior When Needed

If production depends on indexed queries for latency, add one test that verifies index creation or expected query paths after initialization. Even a simple startup assertion can catch missing annotation regressions early.

java
1import org.springframework.data.mongodb.core.MongoTemplate;
2
3@Test
4void collectionExists(org.springframework.beans.factory.annotation.Autowired MongoTemplate template) {
5    assertThat(template.collectionExists(User.class)).isTrue();
6}

For performance critical repositories, pair this with integration benchmarks outside unit test scope.

Keep Test Runtime Fast in CI

Repository tests should remain quick enough to run on every pull request. Use small datasets and avoid unnecessary context startup. A useful target is keeping repository suites under a minute so failures are discovered early.

bash
./gradlew test --tests '*Repository*'

Fast feedback makes it practical to enforce repository tests as a required quality gate in CI.

Common Pitfalls

  • Using full @SpringBootTest for repository-only checks, causing slow feedback.
  • Mocking repository methods instead of validating real query behavior.
  • Sharing mutable fixtures across tests and creating hidden coupling.
  • Forgetting cleanup between tests, leading to order-dependent failures.
  • Mixing service business assertions inside repository test classes.

Summary

  • Use @DataMongoTest for fast and focused repository verification.
  • Keep test data explicit and each assertion narrow.
  • Add Testcontainers tests for behaviors tied to real Mongo versions.
  • Separate repository persistence tests from service logic tests.
  • Enforce test isolation so CI runs remain stable and predictable.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.