How do you configure Embedded MongDB for integration testing in a Spring Boot application?
Since Spring Boot version 1.3 there is an EmbeddedMongoAutoConfiguration
class which comes out of the box. This means that you don't have to create a configuration file at all and if you want to change things you still can.
Auto-configuration for Embedded MongoDB has been added. A dependency on de.flapdoodle.embed:de.flapdoodle.embed.mongo is all that’s necessary to get started. Configuration, such as the version of Mongo to use, can be controlled via application.properties. Please see the documentation for further information. (Spring Boot Release Notes)
The most basic and important configuration that has to be added to the application.properties files is spring.data.mongodb.port=0
(0 means that it will be selected randomly from the free ones)
for more details check: Spring Boot Docs MongoDb
EDIT: see magiccrafter's answer for Spring Boot 1.3+, using EmbeddedMongoAutoConfiguration
.
If you can't use it for any reason, keep reading.
Test class:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
Application.class,
TestMongoConfig.class // <--- Don't forget THIS
})
public class GameRepositoryTest {
@Autowired
private GameRepository gameRepository;
@Test
public void shouldCreateGame() {
Game game = new Game(null, "Far Cry 3");
Game gameCreated = gameRepository.save(game);
assertEquals(gameCreated.getGameId(), gameCreated.getGameId());
assertEquals(game.getName(), gameCreated.getName());
}
}
Simple MongoDB repository:
public interface GameRepository extends MongoRepository<Game, String> {
Game findByName(String name);
}
MongoDB test configuration:
import com.mongodb.Mongo;
import com.mongodb.MongoClientOptions;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
@Configuration
public class TestMongoConfig {
@Autowired
private MongoProperties properties;
@Autowired(required = false)
private MongoClientOptions options;
@Bean(destroyMethod = "close")
public Mongo mongo(MongodProcess mongodProcess) throws IOException {
Net net = mongodProcess.getConfig().net();
properties.setHost(net.getServerAddress().getHostName());
properties.setPort(net.getPort());
return properties.createMongoClient(this.options);
}
@Bean(destroyMethod = "stop")
public MongodProcess mongodProcess(MongodExecutable mongodExecutable) throws IOException {
return mongodExecutable.start();
}
@Bean(destroyMethod = "stop")
public MongodExecutable mongodExecutable(MongodStarter mongodStarter, IMongodConfig iMongodConfig) throws IOException {
return mongodStarter.prepare(iMongodConfig);
}
@Bean
public IMongodConfig mongodConfig() throws IOException {
return new MongodConfigBuilder().version(Version.Main.PRODUCTION).build();
}
@Bean
public MongodStarter mongodStarter() {
return MongodStarter.getDefaultInstance();
}
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>1.48.0</version>
<scope>test</scope>
</dependency>
In version 1.5.7 use just this:
@RunWith(SpringRunner.class)
@DataMongoTest
public class UserRepositoryTests {
@Autowired
UserRepository repository;
@Before
public void setUp() {
User user = new User();
user.setName("test");
repository.save(user);
}
@Test
public void findByName() {
List<User> result = repository.findByName("test");
assertThat(result).hasSize(1).extracting("name").contains("test");
}
}
And
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>