单元测试坑点

it2023-02-27  76

来由:

单元测试时,如果调用方法开启新线程执行任务,可能出现的问题: mongodb异常:

Caused by: com.mongodb.MongoInterruptedException: Interrupted acquiring a permit to retrieve an item from the pool at com.mongodb.internal.connection.ConcurrentPool.acquirePermit(ConcurrentPool.java:203) at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:140) at com.mongodb.internal.connection.ConcurrentPool.get(ConcurrentPool.java:123) at com.mongodb.internal.connection.PowerOfTwoBufferPool.getBuffer(PowerOfTwoBufferPool.java:78) at com.mongodb.connection.SocketStream.read(SocketStream.java:80) at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:555) at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:418) at com.mongodb.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:290) at com.mongodb.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255) at com.mongodb.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:98) at com.mongodb.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:441) at com.mongodb.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:80) at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:189) at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:264) at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:126) at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:118) at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:226) at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:217) at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:120) at com.mongodb.operation.FindOperation$1.call(FindOperation.java:717) at com.mongodb.operation.FindOperation$1.call(FindOperation.java:711) at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:471) at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415) at com.mongodb.operation.FindOperation.execute(FindOperation.java:711) at com.mongodb.operation.FindOperation.execute(FindOperation.java:83) at com.mongodb.Mongo$3.execute(Mongo.java:826) at com.mongodb.MongoIterableImpl.execute(MongoIterableImpl.java:130) at com.mongodb.MongoIterableImpl.iterator(MongoIterableImpl.java:77) at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2440) ... 11 common frames omitted Caused by: java.lang.InterruptedException: null at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1302) at java.util.concurrent.Semaphore.acquire(Semaphore.java:312) at com.mongodb.internal.connection.ConcurrentPool.acquirePermit(ConcurrentPool.java:199) ... 39 common frames omitted java.lang.IllegalStateException: state should be: open at com.mongodb.assertions.Assertions.isTrue(Assertions.java:70) at com.mongodb.connection.BaseCluster.selectServer(BaseCluster.java:82) at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:75) at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:71) at com.mongodb.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:68) at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:221) at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:169) at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:75) at com.mongodb.Mongo.execute(Mongo.java:827) at com.mongodb.Mongo$2.execute(Mongo.java:810) at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:515) at com.mongodb.MongoCollectionImpl.update(MongoCollectionImpl.java:508) at com.mongodb.MongoCollectionImpl.updateOne(MongoCollectionImpl.java:355) at com.test.db.mongoDB.RetryingMongoCollection.updateOne(RetryingMongoCollection.java:909)

redis异常:

Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to ip:port at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56) at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:233) at io.lettuce.core.RedisClient.connectStandalone(RedisClient.java:253) at io.lettuce.core.RedisClient.connect(RedisClient.java:202) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:56) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:957) ... 24 more Caused by: java.lang.IllegalStateException: executor not accepting a task at io.netty.resolver.AddressResolverGroup.getResolver(AddressResolverGroup.java:60) at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:200) at io.netty.bootstrap.Bootstrap.access$000(Bootstrap.java:49) at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:188) at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:174) at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511) at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485) at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424) at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:103) at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84) at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetSuccess(AbstractChannel.java:978) at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:512) at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:423) at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:482) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:163) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ... 1 more

原因:

单元测试时主线程调用新线程执行任务,调用完主线程就关闭了,此时spring生命周期也结束了。而此时子线程任务可能没执行完,可能需要spring容器提供的bean或连接(如mongoTemplate,redisTemplate),但是主线程已经退出了。

解决办法就是不让主线程提前退出。

最新回复(0)