The easiest way to configure Embedded MongoDB
Solution 1
The flapdoodle embedded MongoDB can be integrated with Spring Boot.
-
Declare a dependency on flapdoodle:
<dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <version>2.0.0</version> </dependency>
-
Declare a dependency on the library, to provide a Spring factory bean for flapdoodle's embedded MongoDB:
<dependency> <groupId>cz.jirutka.spring</groupId> <artifactId>embedmongo-spring</artifactId> <version>1.3.1</version> </dependency>
-
Presumably, you have already declared a dependency on
spring-boot-starter-data-mongodb
:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
-
Now, just configure a
MongoTemplate
pointing at the embedded MongoDB instance:@Bean public MongoTemplate mongoTemplate() throws IOException { EmbeddedMongoFactoryBean mongo = new EmbeddedMongoFactoryBean(); mongo.setBindIp("localhost"); MongoClient mongoClient = mongo.getObject(); MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, "test_or_whatever_you_want_to_call_this_db"); return mongoTemplate; }
Solution 2
For Spring Boot 2.2.x with JUnit5
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
Test class
(With ability to set MongoDB version)
@ExtendWith(SpringExtension.class)
@DataMongoTest
class ModelRepoIntegrationTest {
private static final String IP = "localhost";
private static final int PORT = 28017; // <- set MongoDB port
@TestConfiguration
@Import(ModelRepo.class) // <- set the tested repository
// @ComponentScan("com.example.repo") <- or package for several repositories
static class Config {
@Bean
public IMongodConfig embeddedMongoConfiguration() throws IOException {
return new MongodConfigBuilder()
.version(Version.V4_0_2) // <- set MongoDB version
.net(new Net(IP, PORT, Network.localhostIsIPv6()))
.build();
}
}
@Autowired private ModelRepo repo; // <- tested repository
@Autowired private MongoTemplate mongo;
@BeforeEach
void setUp() { // clean db (slower) or collection (faster) before each test
// mongo.getDb().drop();
mongo.remove(new Query(), Model.class);
}
@Test
void create() {
Model model = new Model() // <- tested entity
.setId(UUID.randomUUID())
.setNum(1)
.setText("text");
Model actual = repo.create(model); // <- tested method of the repository
List<Model> models = mongo.findAll(Model.class);
assertThat(models).hasSize(1);
Model expected = models.get(0);
assertThat(actual).isEqualToComparingFieldByField(expected);
}
}
Malakai
Updated on June 22, 2022Comments
-
Malakai almost 2 years
I'm wondering, is there any example how to properly configure embedded
MongoDB
withSpring Boot
?For example, this is how i configure H2 embedded database:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.jndi.JndiObjectFactoryBean; import javax.sql.DataSource; @Configuration @PropertySource({"configs/datasource.properties"}) public class DataSourceConfig { @Bean @Profile("test") public DataSource testDataSource() { return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build(); } }
And this works well, but there is a problem. This approach doesnt provide configuration with MongoDB.
Are there any workarounds?
UPDATE 1:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:run (default-cli) on project XXX: An exception occurred while running. null: InvocationTargetException: Error creating bean with name 'mongoTemplate' defined in class path resource [com/reborn/XXX/config/DataSourceConfig .class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframewor k.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is java.lang.NoClassDefFoundError: de/flapdoodle/embed/mongo/distribu tion/IFeatureAwareVersion: de.flapdoodle.embed.mongo.distribution.IFeatureAwareVersion -> [Help 1]
UPDATE 2:
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.reborn</groupId> <artifactId>xxx</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>xxx</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repositories --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cz.jirutka.spring</groupId> <artifactId>embedmongo-spring</artifactId> <version>1.3.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
DatasourceConfig:
package com.reborn.xxx.config; import com.mongodb.MongoClient; import cz.jirutka.spring.embedmongo.EmbeddedMongoFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoTemplate; import java.io.IOException; @Configuration public class DataSourceConfig { @Bean public MongoTemplate mongoTemplate() throws IOException { EmbeddedMongoFactoryBean mongo = new EmbeddedMongoFactoryBean(); mongo.setBindIp("localhost"); MongoClient mongoClient = mongo.getObject(); MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, "abcd"); return mongoTemplate; } }
UPDATE 3:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:run (default-cli) on project starbucks-finder: An exception occurred while running. null: InvocationTargetException: Error creating bean with name 'mongoTemplate' defined in class path resource [com/reborn/xxx/config/DataSourceConfig .class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframewor k.data.mongodb.core.MongoTemplate]: Factory method 'mongoTemplate' threw exception; nested exception is java.lang.IllegalArgumentException: this version does not support 32Bit: PRODUCTION:Windows:B32 -> [Help 1]