Micronaut测试中MongoClient连接被关闭,如何保持连接全程可用?
MongoDB测试中MongoClient连接保持打开的解决办法
我正在进行MongoDB相关测试,未使用Micronaut Test Resources,而是采用本地Docker容器部署数据库(便于查看测试结果)。我的多项测试依赖MongoDB,但部分测试抛出如下错误:
17:34:09.134 [default-nioEventLoopGroup-3-4] INFO org.mongodb.driver.connection - Opened connection [connectionId{localValue:6, serverValue:26}] to localhost:27018 17:34:09.329 [default-nioEventLoopGroup-3-10] ERROR InternalError - java.lang.IllegalStateException: state should be: open at com.mongodb.assertions.Assertions.isTrue(Assertions.java:79) at com.mongodb.internal.connection.BaseCluster.getDescription(BaseCluster.java:166) at com.mongodb.internal.connection.SingleServerCluster.getDescription(SingleServerCluster.java:44) at com.mongodb.client.internal.MongoClientDelegate.getConnectedClusterDescription(MongoClientDelegate.java:144) at com.mongodb.client.internal.MongoClientDelegate.createClientSession(MongoClientDelegate.java:101) at com.mongodb.client.internal.MongoClientImpl.startSession(MongoClientImpl.java:143) at com.mongodb.client.internal.MongoClientImpl.startSession(MongoClientImpl.java:132) at io.micronaut.data.mongodb.operations.DefaultMongoRepositoryOperations.withClientSession(DefaultMongoRepositoryOperations.java:753) at io.micronaut.data.mongodb.operations.DefaultMongoRepositoryOperations.findAll(DefaultMongoRepositoryOperations.java:253) at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:51) at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:35) at io.micronaut.data.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:81) at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137) at io.micronaut.validation.ValidatingInterceptor.intercept(ValidatingInterceptor.java:143) at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137)
解决步骤
- 保证MongoClient单例实例:在Micronaut测试中,通过
@Singleton注解或依赖注入确保MongoClient全局唯一,避免每个测试类重复创建实例导致连接频繁销毁重建。 - 调整连接池配置:在
application-test.yml中添加连接池参数,防止连接被过早回收:
mongodb: uri: mongodb://localhost:27018/testdb options: maxConnectionIdleTime: 0 # 禁用空闲连接自动超时 maxConnectionLifeTime: 0 # 禁用连接生命周期超时 minConnectionsPerHost: 5 # 维持最小空闲连接数
- 复用测试上下文:在测试类上使用
@MicronautTest(rebuildContext = false),让所有测试共享同一个应用上下文,避免重复初始化和销毁MongoClient。 - 手动管理连接生命周期:编写测试基类,统一初始化和关闭MongoClient,示例代码:
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; public abstract class BaseMongoTest { protected static MongoClient mongoClient; @BeforeAll static void initMongo() { mongoClient = MongoClients.create("mongodb://localhost:27018/testdb"); } @AfterAll static void closeMongo() { if (mongoClient != null) { mongoClient.close(); } } }
- 排查手动关闭逻辑:检查所有测试方法和钩子函数,移除任何手动调用
mongoClient.close()的代码,避免连接被提前关闭。
内容的提问来源于stack exchange,提问作者frynet
相关产品推荐
相关产品推荐

