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
- Introduction
- Prerequisites
- Setting Up the Project
- Adding Dependencies
- Configuring Embedded MongoDB
- Creating a Repository
- Writing Unit Tests
- Running the Tests
- 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>
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'
}
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"));
}
}
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> {
}
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
}
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");
}
}
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
If using Gradle, run the tests with:
gradle test
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)