How to make the junit tests use the embedded mongoDB in a springboot application?
An alternative would be to run entire spring boot application in test. In this case your spring boot application will be discovered automatically and embedded mongoDB will be downloaded and started by Spring Boot
@RunWith(SpringRunner.class)
@SpringBootTest
public class YourSpringBootApplicationTests {
08:12:14.676 INFO EmbeddedMongo:42 - note: noprealloc may hurt performance in many applications 08:12:14.694 INFO EmbeddedMongo:42 - 2017-12-31T08:12:14.693+0200 I CONTROL [initandlisten] MongoDB starting : pid=2246 port=52299 08:12:22.005 INFO connection:71 - Opened connection [connectionId{localValue:2, serverValue:2}] to localhost:52299
In case of your example you might modify the code in order to start embedded Mongo on different port:
-
add test/resoures/test.properties file in order to override properties from application.properties
mongo.db.name=person_testDB mongo.db.url=localhost mongo.db.port=12345
-
modify MongoDBConfig: add MONGO_DB_PORT field
@EnableMongoRepositories public class MongoDBConfig { @Value("${mongo.db.url}") private String MONGO_DB_URL; @Value(("${mongo.db.port:27017}")) private int MONGO_DB_PORT; @Value("${mongo.db.name}") private String MONGO_DB_NAME; @Bean public MongoTemplate mongoTemplate() { MongoClient mongoClient = new MongoClient(MONGO_DB_URL, MONGO_DB_PORT); MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, MONGO_DB_NAME); return mongoTemplate; } }
-
modify test class: remove @DataMongoTest annotation. This annotation forces starting embedded mongoDB instance
static MongodExecutable mongodExecutable; @BeforeClass public static void setup() throws Exception { MongodStarter starter = MongodStarter.getDefaultInstance(); String bindIp = "localhost"; int port = 12345; IMongodConfig mongodConfig = new MongodConfigBuilder() .version(Version.Main.PRODUCTION) .net(new Net(bindIp, port, Network.localhostIsIPv6())) .build(); mongodExecutable = null; try { mongodExecutable = starter.prepare(mongodConfig); mongodExecutable.start(); } catch (Exception e){ // log exception here if (mongodExecutable != null) mongodExecutable.stop(); } } @AfterClass public static void teardown() throws Exception { if (mongodExecutable != null) mongodExecutable.stop(); }
One more way is to use MongoRepository and init embedded Mongo as part of test @Configuration class: it's outlined here: How do you configure Embedded MongDB for integration testing in a Spring Boot application?
SkyBlue
Updated on July 20, 2022Comments
-
SkyBlue almost 2 years
I am learning springboot and have created a simple springboot application. I want it to use the embedded mongoDB when it runs the unit tests and the external mongoDB for the rest of the application. However it uses the external mongoDB for the unit tests instead of the embedded one. I have following two dependencies in my POM.
<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> <scope>test</scope> </dependency>
my properties file has the following:
# MongoDB properties mongo.db.name=person_testDB mongo.db.url=localhost #external Mongo url spring.data.mongodb.uri=mongodb://localhost:27017/personDB
I have a config file(MongoDBConfig.java) which includes embedded MongoDB configurations:
@EnableMongoRepositories public class MongoDBConfig { @Value("${mongo.db.url}") private String MONGO_DB_URL; @Value("${mongo.db.name}") private String MONGO_DB_NAME; @Bean public MongoTemplate mongoTemplate() { MongoClient mongoClient = new MongoClient(MONGO_DB_URL); MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, MONGO_DB_NAME); return mongoTemplate; } }
Following is my
PersonService.java
class:@Service public class PersonService { private static final Logger logger = LoggerFactory.getLogger(PersonService.class); @Autowired MongoTemplate mongoTemplate; public void savePerson(Person person) { String name = person.getName(); String collectionName = name.substring(0, 1); mongoTemplate.save(person, collectionName); } }
My unit test for the PersonsService class is as follows:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {MongoDBConfig.class}) @SpringBootTest(classes = PersonService.class) @DataMongoTest public class PersonServiceTest { @Autowired PersonService personService; MongodForTestsFactory factory; MongoClient mongo; @Before public void setup() throws Exception { factory = MongodForTestsFactory.with(Version.Main.PRODUCTION); mongo = factory.newMongo(); } @After public void teardown() throws Exception { if (factory != null) factory.shutdown(); } @Test public void testSave(){ Person person = new Person("Bob Smith " , 25); personService.savePerson(person); } }
It creates the collection name and the document name correctly in the external MongoDB which is not what I want. How can I restrict the unitTests to an embedded Mongo?