java - How do you configure Embedded MongDB for integration testing in a Spring Boot application? -
i have simple spring boot application exposes small rest api , retrieves data instance of mongodb. queries mongodb instance go through spring data based repository. key bits of code below.
// main application class @enableautoconfiguration(exclude={mongoautoconfiguration.class, mongodataautoconfiguration.class}) @componentscan @import(mongoconfig.class) public class productapplication { public static void main(string[] args) { springapplication.run(productapplication.class, args); } }
// product repository spring data public interface productrepository extends mongorepository<product, string> { page<product> findall(pageable pageable); optional<product> findbylinenumber(string linenumber); }
// configuration "live" connections @configuration public class mongoconfig { @value("${product.mongo.host}") private string mongohost; @value("${product.mongo.port}") private string mongoport; @value("${product.mongo.database}") private string mongodatabase; @bean(name="mongoclient") public mongoclient mongoclient() throws ioexception { return new mongoclient(mongohost, integer.parseint(mongoport)); } @autowired @bean(name="mongodbfactory") public mongodbfactory mongodbfactory(mongoclient mongoclient) { return new simplemongodbfactory(mongoclient, mongodatabase); } @autowired @bean(name="mongotemplate") public mongotemplate mongotemplate(mongoclient mongoclient) { return new mongotemplate(mongoclient, mongodatabase); } }
@configuration @enablemongorepositories public class embeddedmongoconfig { private static final string db_name = "integrationtest"; private static final int db_port = 12345; private static final string db_host = "localhost"; private static final string db_collection = "products"; private mongodexecutable mongodexecutable = null; @bean(name="mongoclient") public mongoclient mongoclient() throws ioexception { // lots of calls here de.flapdoodle.embed.mongo code base // create embedded db , insert json data } @autowired @bean(name="mongodbfactory") public mongodbfactory mongodbfactory(mongoclient mongoclient) { return new simplemongodbfactory(mongoclient, db_name); } @autowired @bean(name="mongotemplate") public mongotemplate mongotemplate(mongoclient mongoclient) { return new mongotemplate(mongoclient, db_name); } @predestroy public void shutdownembeddedmongodb() { if (this.mongodexecutable != null) { this.mongodexecutable.stop(); } } }
@runwith(springjunit4classrunner.class) @springapplicationconfiguration(classes = testproductapplication.class) @integrationtest @webappconfiguration public class wtrproductapplicationtests { @test public void contextloads() { // tests empty } }
@enableautoconfiguration(exclude={mongoautoconfiguration.class, mongodataautoconfiguration.class}) @componentscan @import(embeddedmongoconfig.class) public class testproductapplication { public static void main(string[] args) { springapplication.run(testproductapplication.class, args); } }
so idea here have integration tests (empty @ moment) connect embedded mongo instance , not "live" one. however, doesn't work. can see tests connecting "live" instance of mongo, , if shut down build fails still attempting connect live instance of mongo. know why is? how tests connect embedded instance?
this works me.
test class:
@runwith(springjunit4classrunner.class) @springapplicationconfiguration(classes = { application.class, testmongoconfig.class // <--- don't forget }) 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>
Comments
Post a Comment