SpringBoot 3.0.0集成嵌入式MongoDB测试失败的解决方法
Spring Boot 3.0.0 嵌入式MongoDB测试连接超时问题解决
在Spring Boot 2.7.7中可正常运行的嵌入式MongoDB测试代码,升级到3.0.0版本后出现连接超时被拒绝的错误,以下是问题排查和解决方案:
问题重现
测试执行时抛出连接超时异常:
org.springframework.dao.DataAccessResourceFailureException: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: no further information}}]
相关配置与代码
pom.xml依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </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> <version>3.5.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> <version>3.0.0</version> </dependency> </dependencies>
application.properties配置
spring.data.mongodb.database=test spring.data.mongodb.port=27017 spring.mongodb.embedded.version=4.0.2
测试代码
@DataMongoTest @ExtendWith(SpringExtension.class) public class MongoDbSpringIntegrationTest { @DisplayName("given object to save" + " when save object using MongoDB template" + " then object is saved") @Test public void test(@Autowired MongoTemplate mongoTemplate) { // given DBObject objectToSave = BasicDBObjectBuilder.start() .add("key", "value") .get(); // when mongoTemplate.save(objectToSave, "collection"); // then assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") .containsOnly("value"); } }
解决方案
1. 调整依赖配置
Spring Boot 3.x对嵌入式MongoDB的依赖管理做了优化,移除手动指定的de.flapdoodle.embed.mongo版本号,让Spring Boot自动适配兼容版本:
<dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <scope>test</scope> <!-- 移除手动指定的version --> </dependency>
同时确保pom.xml继承Spring Boot parent,避免手动指定spring-boot-starter-data-mongodb版本:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.0</version> <relativePath/> </parent>
2. 修改配置属性
Spring Boot 3.x中嵌入式MongoDB的配置属性前缀变更,且不要指定固定端口(嵌入式Mongo默认使用随机端口,Spring Boot会自动配置连接):
修改application.properties为:
spring.data.mongodb.database=test # 移除spring.data.mongodb.port=27017 spring.data.mongodb.embedded.version=4.0.2
(原spring.mongodb.embedded.version已被弃用,改用spring.data.mongodb.embedded.version)
3. 优化测试代码
@DataMongoTest在Spring Boot 3.x中已自动包含@ExtendWith(SpringExtension.class),可移除该注解;- 替换旧的
DBObjectAPI为MongoDB Driver 4.x推荐的Document:
@DataMongoTest public class MongoDbSpringIntegrationTest { @DisplayName("给定要保存的对象,使用MongoDB模板保存后,对象成功存入") @Test public void test(@Autowired MongoTemplate mongoTemplate) { // given Document objectToSave = new Document("key", "value"); // when mongoTemplate.save(objectToSave, "collection"); // then assertThat(mongoTemplate.findAll(Document.class, "collection")) .extracting(doc -> doc.getString("key")) .containsOnly("value"); } }
4. 显式启用嵌入式Mongo配置
若以上调整仍有问题,添加@AutoConfigureEmbeddedMongo注解强制启用自动配置:
@DataMongoTest @AutoConfigureEmbeddedMongo public class MongoDbSpringIntegrationTest { // 测试代码... }
关键原因说明
- Spring Boot 3.x升级MongoDB Driver到4.x版本,手动指定的旧版
de.flapdoodle.embed.mongo存在兼容性冲突; - 固定端口27017可能被本地Mongo占用,或嵌入式Mongo未启动在该端口,导致连接拒绝;
- 配置属性前缀变更,旧属性无法正确加载Mongo版本,引发启动失败。
内容的提问来源于stack exchange,提问作者Suori
相关产品推荐
相关产品推荐

