DEV Community

Cover image for How to Integrate Embedded MongoDB for Unit Testing in a Spring Application
FullStackJava
FullStackJava

Posted on

How to Integrate Embedded MongoDB for Unit Testing in a Spring Application

Unit testing is a crucial part of software development, ensuring that individual components of an application work as expected. When it comes to testing data persistence layers in a Spring application, MongoDB is a popular choice. To facilitate unit testing with MongoDB, we can use an embedded MongoDB instance. This eliminates the need for an actual running MongoDB server, making tests more reliable and easier to set up.

In this blog, we will walk through the steps required to integrate embedded MongoDB into a Spring application for unit testing.

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up the Project
  4. Adding Dependencies
  5. Configuring Embedded MongoDB
  6. Creating a Repository
  7. Writing Unit Tests
  8. Running the Tests
  9. Conclusion

Introduction

Embedded MongoDB allows developers to run a MongoDB server embedded within the Java application, specifically for testing purposes. This ensures that tests are run in isolation and are not dependent on an external MongoDB instance. By using embedded MongoDB, we can simulate a real MongoDB environment and perform integration tests on our repositories.

Prerequisites

Before we begin, ensure you have the following installed on your system:

  • Java Development Kit (JDK) 8 or later
  • Maven or Gradle build tool
  • An Integrated Development Environment (IDE) like IntelliJ IDEA or Eclipse

Setting Up the Project

First, create a new Spring Boot project using Spring Initializr or your preferred method. Ensure that you include Spring Data MongoDB as a dependency.

Adding Dependencies

To use embedded MongoDB, we need to add the de.flapdoodle.embed.mongo dependency to our project. Additionally, we will add Spring Data MongoDB for interacting with MongoDB.

If you are using Maven, add the following dependencies to your pom.xml file:

<dependencies>
    <!-- Spring Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>

    <!-- Embedded MongoDB -->
    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <version>3.2.1</version>
    </dependency>

    <!-- Spring Boot Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

For Gradle, add the following dependencies to your build.gradle file:

dependencies {
    // Spring Data MongoDB
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'

    // Embedded MongoDB
    testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:3.2.1'

    // Spring Boot Test
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Enter fullscreen mode Exit fullscreen mode

Configuring Embedded MongoDB

Next, we need to configure Spring to use the embedded MongoDB instance during tests. Create a configuration class for this purpose.

package com.example.demo;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;

import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;

import java.io.IOException;

@TestConfiguration
public class EmbeddedMongoConfig {

    @Bean
    public MongodExecutable embeddedMongoServer() throws IOException {
        IMongodConfig mongodConfig = new MongodConfigBuilder()
                .version(Version.Main.PRODUCTION)
                .net(new Net("localhost", 27017, true))
                .build();

        MongodStarter starter = MongodStarter.getDefaultInstance();
        return starter.prepare(mongodConfig);
    }

    @Bean
    public MongoTemplate mongoTemplate() throws IOException {
        embeddedMongoServer().start();
        return new MongoTemplate(new SimpleMongoClientDbFactory("mongodb://localhost:27017/test"));
    }
}
Enter fullscreen mode Exit fullscreen mode

This configuration class sets up an embedded MongoDB instance that runs on localhost at port 27017.

Creating a Repository

Create a simple repository interface to interact with MongoDB. For this example, let's assume we have a User entity.

package com.example.demo.repository;

import com.example.demo.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepository extends MongoRepository<User, String> {
}
Enter fullscreen mode Exit fullscreen mode

Create the User entity:

package com.example.demo.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class User {

    @Id
    private String id;
    private String name;
    private String email;

    // Constructors, getters, and setters
}
Enter fullscreen mode Exit fullscreen mode

Writing Unit Tests

Now, let's write unit tests to verify the functionality of the UserRepository. We'll use Spring's testing support to load the application context and the embedded MongoDB instance.

package com.example.demo;

import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
@Import(EmbeddedMongoConfig.class)
@ActiveProfiles("test")
public class UserRepositoryTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void testSaveAndFindUser() {
        User user = new User();
        user.setName("John Doe");
        user.setEmail("john.doe@example.com");

        userRepository.save(user);

        Optional<User> foundUser = userRepository.findById(user.getId());
        assertThat(foundUser).isPresent();
        assertThat(foundUser.get().getName()).isEqualTo("John Doe");
        assertThat(foundUser.get().getEmail()).isEqualTo("john.doe@example.com");
    }
}
Enter fullscreen mode Exit fullscreen mode

Running the Tests

Run the tests using your IDE or build tool. The embedded MongoDB instance will start automatically before the tests and shut down after the tests are completed.

If using Maven, run the tests with:

mvn test
Enter fullscreen mode Exit fullscreen mode

If using Gradle, run the tests with:

gradle test
Enter fullscreen mode Exit fullscreen mode

Conclusion

Integrating embedded MongoDB into a Spring application for unit testing provides a convenient and efficient way to test MongoDB-related functionality without the need for an external MongoDB server. By following the steps outlined in this blog, you can set up and use embedded MongoDB in your Spring application, ensuring your data persistence layer is thoroughly tested.

Using embedded MongoDB ensures that your tests are isolated, repeatable, and easy to manage, leading to more robust and reliable applications.

Top comments (0)