我正在学习springboot,并创建了一个简单的springboot应用程序。我希望它在运行单元测试时使用嵌入式mongoDB,并在其余应用程序中使用外部mongoDB。但是,它使用外部mongoDB进行单元测试,而不是使用嵌入式mongoDB。我的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>
我的属性文件具有以下内容:
# MongoDB properties mongo.db.name=person_testDB mongo.db.url=localhost #external Mongo url spring.data.mongodb.uri=mongodb://localhost:27017/personDB
我有一个配置文件(MongoDBConfig.java),其中包含嵌入式MongoDB配置:
@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; } }
以下是我的PersonService.java课程:
PersonService.java
@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); } }
我对PersonsService类的单元测试如下:
@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); } }
它在外部MongoDB中正确创建了集合名称和文档名称,这不是我想要的。如何将unitTests限制为嵌入式Mongo?
一种替代方法是在测试中运行整个spring boot应用程序。在这种情况下,您的spring boot应用程序将被自动发现,嵌入式mongoDB将由Spring Boot下载并启动。
@RunWith(SpringRunner.class) @SpringBootTest public class YourSpringBootApplicationTests {
08:12:14.676 INFO EmbeddedMongo:42-注意:noprealloc可能会损害许多应用程序的性能08:12:14.694 INFO EmbeddedMongo:42-2017-12-31T08:12:14.693 + 0200 I CONTROL [initandlisten] MongoDB开始:pid = 2246 port = 52299 08:12:22.005 INFO连接:71-已打开到本地主机的连接[connectionId {localValue:2,serverValue:2}]
在您的示例中,您可以修改代码以在其他端口上启动嵌入式Mongo:
mongo.db.name=person_testDB mongo.db.url=localhost mongo.db.port=12345
@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; } }
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(); }
另一种方法是使用MongoRepository和init嵌入式Mongo作为测试@Configuration类的一部分:此处概述:如何配置嵌入式MongDB以在Spring Boot应用程序中进行集成测试?