NutzCN Logo
问答 一次性执行两个单元测试用例,第二个用例jedis拿不到连接
发布于 2662天前 作者 hziee514 2456 次浏览 复制 上一个帖子 下一个帖子
标签:

一次性执行TestSuite下的两个用例,这两个用例都会用到redis,然后第二个用例一定会报这个错。

请问作者君能指点一下解决这个问题的思路吗?

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
	at redis.clients.util.Pool.getResource(Pool.java:53)
	at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
	at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
	at org.nutz.integration.jedis.JedisAgent.jedis(JedisAgent.java:49)
	at org.nutz.integration.jedis.RedisInterceptor.filter(RedisInterceptor.java:22)
	at org.nutz.aop.InterceptorChain.doChain(InterceptorChain.java:60)
	at org.nutz.integration.jedis.RedisService$$NUTZAOP.incr(RedisService.java:1)
	at cn.caratel.cloud.voipBackend.util.NoUtils.makeOrderNo(NoUtils.java:30)
	at cn.caratel.cloud.voipBackend.biz.ChargeBiz.wxscan(ChargeBiz.java:273)
	at cn.caratel.cloud.voipBackend.biz.ChargeBizTest.testWxScan(ChargeBizTest.java:41)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.nutz.mock.NutTestRunner.runChild(NutTestRunner.java:33)
	at org.nutz.mock.NutTestRunner.runChild(NutTestRunner.java:14)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalStateException: Pool not open
	at org.apache.commons.pool2.impl.BaseGenericObjectPool.assertOpen(BaseGenericObjectPool.java:672)
	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:412)
	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
	at redis.clients.util.Pool.getResource(Pool.java:49)
	... 33 more

public class MyTestRunner extends NutTestRunner {

	public MyTestRunner(Class<?> klass) throws InitializationError {
		super(klass);
	}

	@Override
	protected Ioc createIoc() {
		Ioc ioc = super.createIoc();
		PropertiesProxy conf = ioc.get(PropertiesProxy.class, "conf");

        conf.put("redis.host", "127.0.0.1");
        conf.put("redis.port", "6379");
        conf.put("redis.timeout", "2000");
        conf.put("redis.database", "3");
        
        MockServletContext servletContext = new MockServletContext();
        Mvcs.setServletContext(servletContext);
        
        MockHttpSession session = Mock.servlet.session(servletContext);
        
        MockHttpServletRequest request = Mock.servlet.request();
        request.setSession(session);
        
        MockHttpServletResponse response = new MockHttpServletResponse();

        Mvcs.set("test", request, response);
        
        Mvcs.setIoc(ioc);
        
		return ioc;
	}

	@Override
	protected Class<?> getMainModule() {
		return EntryModule.class;
	}

}
8 回复

打印一下看看创建了多少次的ioc容器

有可能是aop的问题

是看createIoc这个函数的调用次数吗?
每个用例执行前都会调用createIoc

试试这样写, 覆盖 runChild 方法

    protected void runChild(FrameworkMethod method, RunNotifier notifier) {
        if (isIgnored(method)) {
            super.runChild(method, notifier);
            return;
        }
        Ioc ioc = createIoc();
        try {
            iocHolder.set(ioc);
            super.runChild(method, notifier);
        } finally {
            iocHolder.remove();
            //ioc.depose(); 注释掉这一行试试
        }
    }

@wendal 现在能正常跑了,非常感谢!!!

这个是什么原因呢?

Aop的时候把第一次运行时创建的JedisPool固化在里面了, 应该是这样

得想想怎么真正解决一下

看起来好像很麻烦的样子。不管了,能正常跑起来就行了。

添加回复
请先登陆
回到顶部